From 6300fcbef816e9776010151e1fa5967d76b73ed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=88=E5=A4=95=E8=8A=B1=E6=99=A8?= <825210484@qq.com> Date: Thu, 23 May 2024 14:52:30 +0800 Subject: [PATCH] =?UTF-8?q?wps=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oaassist/.gitignore | 2 - oaassist/EtOAAssist/LICENSE | 25 - oaassist/EtOAAssist/README.md | 19 - oaassist/EtOAAssist/icon/w_Save.png | Bin 13913 -> 0 bytes oaassist/EtOAAssist/icon/w_SaveAs.png | Bin 14246 -> 0 bytes oaassist/EtOAAssist/index.html | 5 - oaassist/EtOAAssist/js/common/common.js | 229 -- oaassist/EtOAAssist/js/common/func_docEvents.js | 251 -- oaassist/EtOAAssist/js/common/func_docProcess.js | 354 --- oaassist/EtOAAssist/js/common/func_oastarter.js | 56 - oaassist/EtOAAssist/js/common/func_tabcontrol.js | 441 --- oaassist/EtOAAssist/js/main.js | 9 - oaassist/EtOAAssist/package.json | 12 - oaassist/EtOAAssist/ribbon.xml | 14 - oaassist/README.md | 121 - oaassist/WppOAAssist/LICENSE | 25 - oaassist/WppOAAssist/README.md | 19 - oaassist/WppOAAssist/icon/w_Save.png | Bin 13913 -> 0 bytes oaassist/WppOAAssist/icon/w_SaveAs.png | Bin 14246 -> 0 bytes oaassist/WppOAAssist/index.html | 5 - oaassist/WppOAAssist/js/common/common.js | 289 -- oaassist/WppOAAssist/js/common/func_docEvents.js | 103 - oaassist/WppOAAssist/js/common/func_docProcess.js | 312 -- oaassist/WppOAAssist/js/common/func_oastarter.js | 53 - oaassist/WppOAAssist/js/common/func_tabcontrol.js | 407 --- oaassist/WppOAAssist/js/main.js | 9 - oaassist/WppOAAssist/package.json | 12 - oaassist/WppOAAssist/ribbon.xml | 33 - oaassist/WpsOAAssist/LICENSE | 326 -- oaassist/WpsOAAssist/QRCode.html | 82 - oaassist/WpsOAAssist/README.md | 27 - oaassist/WpsOAAssist/icon/3.svg | 19 - oaassist/WpsOAAssist/icon/c_bookmark.png | Bin 14147 -> 0 bytes oaassist/WpsOAAssist/icon/c_default.png | Bin 2601 -> 0 bytes oaassist/WpsOAAssist/icon/c_printDoc.png | Bin 1547 -> 0 bytes oaassist/WpsOAAssist/icon/c_seal.png | Bin 2073 -> 0 bytes oaassist/WpsOAAssist/icon/newFromTemp.svg | 22 - oaassist/WpsOAAssist/icon/w_AcceptRev.png | Bin 1887 -> 0 bytes oaassist/WpsOAAssist/icon/w_BackDoc.png | Bin 4610 -> 0 bytes oaassist/WpsOAAssist/icon/w_CloseRev.png | Bin 1656 -> 0 bytes oaassist/WpsOAAssist/icon/w_CloseRev1 (2).png | Bin 861 -> 0 bytes oaassist/WpsOAAssist/icon/w_CloseRev3.png | Bin 767 -> 0 bytes oaassist/WpsOAAssist/icon/w_DeleteRev.png | Bin 610 -> 0 bytes oaassist/WpsOAAssist/icon/w_DocClear.png | Bin 1152 -> 0 bytes oaassist/WpsOAAssist/icon/w_DocClound.png | Bin 3281 -> 0 bytes oaassist/WpsOAAssist/icon/w_DocOFD.png | Bin 2334 -> 0 bytes oaassist/WpsOAAssist/icon/w_DocQr.png | Bin 834 -> 0 bytes oaassist/WpsOAAssist/icon/w_DocQr1.png | Bin 1090 -> 0 bytes oaassist/WpsOAAssist/icon/w_DocRevis.png | Bin 2387 -> 0 bytes oaassist/WpsOAAssist/icon/w_DocUOF.png | Bin 2272 -> 0 bytes oaassist/WpsOAAssist/icon/w_GovDoc.png | Bin 1395 -> 0 bytes oaassist/WpsOAAssist/icon/w_ImportDoc.png | Bin 1608 -> 0 bytes oaassist/WpsOAAssist/icon/w_ImportDoc1.png | Bin 1140 -> 0 bytes oaassist/WpsOAAssist/icon/w_InsDate.png | Bin 1816 -> 0 bytes oaassist/WpsOAAssist/icon/w_InsPicture.png | Bin 1099 -> 0 bytes oaassist/WpsOAAssist/icon/w_InsPictures.png | Bin 1394 -> 0 bytes oaassist/WpsOAAssist/icon/w_OpenRev.png | Bin 1804 -> 0 bytes oaassist/WpsOAAssist/icon/w_OpenRev2.png | Bin 2040 -> 0 bytes oaassist/WpsOAAssist/icon/w_PDF.png | Bin 15072 -> 0 bytes oaassist/WpsOAAssist/icon/w_PageGear.png | Bin 1857 -> 0 bytes oaassist/WpsOAAssist/icon/w_RejectRev.png | Bin 1926 -> 0 bytes oaassist/WpsOAAssist/icon/w_Save.png | Bin 13913 -> 0 bytes oaassist/WpsOAAssist/icon/w_SaveAs.png | Bin 14246 -> 0 bytes oaassist/WpsOAAssist/icon/w_Scanner16.png | Bin 1317 -> 0 bytes oaassist/WpsOAAssist/icon/w_WPSCloud.png | Bin 1526 -> 0 bytes oaassist/WpsOAAssist/importTemplate.html | 173 - oaassist/WpsOAAssist/index.html | 5 - oaassist/WpsOAAssist/js/common/common.js | 535 ---- oaassist/WpsOAAssist/js/common/enum.js | 115 - oaassist/WpsOAAssist/js/common/func_docEvents.js | 232 -- oaassist/WpsOAAssist/js/common/func_docProcess.js | 904 ------ oaassist/WpsOAAssist/js/common/func_oastarter.js | 146 - oaassist/WpsOAAssist/js/common/func_tabcontrol.js | 1431 --------- oaassist/WpsOAAssist/js/common/time.js | 157 - oaassist/WpsOAAssist/js/main.js | 12 - oaassist/WpsOAAssist/otherslib/lib/formdata.js | 37 - oaassist/WpsOAAssist/otherslib/lib/jquery.min.js | 6 - oaassist/WpsOAAssist/otherslib/lib/qrcode.min.js | 1 - oaassist/WpsOAAssist/otherslib/lib/vue.min.js | 6 - oaassist/WpsOAAssist/package.json | 12 - oaassist/WpsOAAssist/redhead.html | 142 - oaassist/WpsOAAssist/ribbon.xml | 148 - oaassist/WpsOAAssist/selectBookmark.html | 195 -- oaassist/WpsOAAssist/selectSeal.html | 205 -- oaassist/WpsOAAssist/setUserName.html | 34 - oaassist/WpsOAAssist/taskpane.html | 143 - oaassist/WpsOAAssist/template/OA模板公章.png | Bin 10207 -> 0 bytes oaassist/WpsOAAssist/template/模板.docx | Bin 11755 -> 0 bytes oaassist/WpsOAAssist/template/红头文件.docx | Bin 13608 -> 0 bytes oaassist/server/.gitignore | 4 - oaassist/server/StartupServer.js | 310 -- oaassist/server/package.json | 23 - oaassist/server/wwwroot/.gitignore | 2 - oaassist/server/wwwroot/LICENSE | 25 - oaassist/server/wwwroot/README.md | 17 - oaassist/server/wwwroot/demo.html | 208 -- oaassist/server/wwwroot/file/HelloServlet.java | 140 - oaassist/server/wwwroot/file/OA模板公章.png | Bin 10207 -> 0 bytes oaassist/server/wwwroot/file/templateData.json | 22 - oaassist/server/wwwroot/file/公文样章.wps | Bin 35342 -> 0 bytes oaassist/server/wwwroot/file/样章.docx | Bin 15700 -> 0 bytes oaassist/server/wwwroot/file/样章.pptx | Bin 63515 -> 0 bytes oaassist/server/wwwroot/file/样章.xlsx | Bin 13971 -> 0 bytes oaassist/server/wwwroot/file/样章2.docx | Bin 11755 -> 0 bytes oaassist/server/wwwroot/file/红头文件.docx | Bin 13608 -> 0 bytes oaassist/server/wwwroot/index.html | 40 - oaassist/server/wwwroot/jsplugins.xml | 18 - oaassist/server/wwwroot/resource/WPS.png | Bin 9381 -> 0 bytes oaassist/server/wwwroot/resource/css/demo.css | 71 - oaassist/server/wwwroot/resource/et.html | 53 - .../wwwroot/resource/highlight/highlight.pack.js | 3319 -------------------- .../server/wwwroot/resource/highlight/zenburn.css | 115 - oaassist/server/wwwroot/resource/js/demo.js | 226 -- oaassist/server/wwwroot/resource/js/et.js | 237 -- oaassist/server/wwwroot/resource/js/utils/json2.js | 433 --- oaassist/server/wwwroot/resource/js/wpp.js | 238 -- oaassist/server/wwwroot/resource/js/wps.js | 924 ------ oaassist/server/wwwroot/resource/js/wps_sdk.js | 957 ------ oaassist/server/wwwroot/resource/js/wpsjsrpcsdk.js | 1355 -------- oaassist/server/wwwroot/resource/wpp.html | 55 - oaassist/server/wwwroot/resource/wps.html | 67 - test/oaassist/.gitignore | 2 + test/oaassist/EtOAAssist/LICENSE | 25 + test/oaassist/EtOAAssist/README.md | 19 + test/oaassist/EtOAAssist/icon/w_Save.png | Bin 0 -> 13913 bytes test/oaassist/EtOAAssist/icon/w_SaveAs.png | Bin 0 -> 14246 bytes test/oaassist/EtOAAssist/index.html | 5 + test/oaassist/EtOAAssist/js/common/common.js | 229 ++ .../EtOAAssist/js/common/func_docEvents.js | 251 ++ .../EtOAAssist/js/common/func_docProcess.js | 354 +++ .../EtOAAssist/js/common/func_oastarter.js | 56 + .../EtOAAssist/js/common/func_tabcontrol.js | 441 +++ test/oaassist/EtOAAssist/js/main.js | 9 + test/oaassist/EtOAAssist/package.json | 12 + test/oaassist/EtOAAssist/ribbon.xml | 14 + test/oaassist/README.md | 121 + test/oaassist/WppOAAssist/LICENSE | 25 + test/oaassist/WppOAAssist/README.md | 19 + test/oaassist/WppOAAssist/icon/w_Save.png | Bin 0 -> 13913 bytes test/oaassist/WppOAAssist/icon/w_SaveAs.png | Bin 0 -> 14246 bytes test/oaassist/WppOAAssist/index.html | 5 + test/oaassist/WppOAAssist/js/common/common.js | 289 ++ .../WppOAAssist/js/common/func_docEvents.js | 103 + .../WppOAAssist/js/common/func_docProcess.js | 312 ++ .../WppOAAssist/js/common/func_oastarter.js | 53 + .../WppOAAssist/js/common/func_tabcontrol.js | 407 +++ test/oaassist/WppOAAssist/js/main.js | 9 + test/oaassist/WppOAAssist/package.json | 12 + test/oaassist/WppOAAssist/ribbon.xml | 33 + test/oaassist/WpsOAAssist/LICENSE | 326 ++ test/oaassist/WpsOAAssist/QRCode.html | 82 + test/oaassist/WpsOAAssist/README.md | 27 + test/oaassist/WpsOAAssist/icon/3.svg | 19 + test/oaassist/WpsOAAssist/icon/c_bookmark.png | Bin 0 -> 14147 bytes test/oaassist/WpsOAAssist/icon/c_default.png | Bin 0 -> 2601 bytes test/oaassist/WpsOAAssist/icon/c_printDoc.png | Bin 0 -> 1547 bytes test/oaassist/WpsOAAssist/icon/c_seal.png | Bin 0 -> 2073 bytes test/oaassist/WpsOAAssist/icon/newFromTemp.svg | 22 + test/oaassist/WpsOAAssist/icon/w_AcceptRev.png | Bin 0 -> 1887 bytes test/oaassist/WpsOAAssist/icon/w_BackDoc.png | Bin 0 -> 4610 bytes test/oaassist/WpsOAAssist/icon/w_CloseRev.png | Bin 0 -> 1656 bytes test/oaassist/WpsOAAssist/icon/w_CloseRev1 (2).png | Bin 0 -> 861 bytes test/oaassist/WpsOAAssist/icon/w_CloseRev3.png | Bin 0 -> 767 bytes test/oaassist/WpsOAAssist/icon/w_DeleteRev.png | Bin 0 -> 610 bytes test/oaassist/WpsOAAssist/icon/w_DocClear.png | Bin 0 -> 1152 bytes test/oaassist/WpsOAAssist/icon/w_DocClound.png | Bin 0 -> 3281 bytes test/oaassist/WpsOAAssist/icon/w_DocOFD.png | Bin 0 -> 2334 bytes test/oaassist/WpsOAAssist/icon/w_DocQr.png | Bin 0 -> 834 bytes test/oaassist/WpsOAAssist/icon/w_DocQr1.png | Bin 0 -> 1090 bytes test/oaassist/WpsOAAssist/icon/w_DocRevis.png | Bin 0 -> 2387 bytes test/oaassist/WpsOAAssist/icon/w_DocUOF.png | Bin 0 -> 2272 bytes test/oaassist/WpsOAAssist/icon/w_GovDoc.png | Bin 0 -> 1395 bytes test/oaassist/WpsOAAssist/icon/w_ImportDoc.png | Bin 0 -> 1608 bytes test/oaassist/WpsOAAssist/icon/w_ImportDoc1.png | Bin 0 -> 1140 bytes test/oaassist/WpsOAAssist/icon/w_InsDate.png | Bin 0 -> 1816 bytes test/oaassist/WpsOAAssist/icon/w_InsPicture.png | Bin 0 -> 1099 bytes test/oaassist/WpsOAAssist/icon/w_InsPictures.png | Bin 0 -> 1394 bytes test/oaassist/WpsOAAssist/icon/w_OpenRev.png | Bin 0 -> 1804 bytes test/oaassist/WpsOAAssist/icon/w_OpenRev2.png | Bin 0 -> 2040 bytes test/oaassist/WpsOAAssist/icon/w_PDF.png | Bin 0 -> 15072 bytes test/oaassist/WpsOAAssist/icon/w_PageGear.png | Bin 0 -> 1857 bytes test/oaassist/WpsOAAssist/icon/w_RejectRev.png | Bin 0 -> 1926 bytes test/oaassist/WpsOAAssist/icon/w_Save.png | Bin 0 -> 13913 bytes test/oaassist/WpsOAAssist/icon/w_SaveAs.png | Bin 0 -> 14246 bytes test/oaassist/WpsOAAssist/icon/w_Scanner16.png | Bin 0 -> 1317 bytes test/oaassist/WpsOAAssist/icon/w_WPSCloud.png | Bin 0 -> 1526 bytes test/oaassist/WpsOAAssist/importTemplate.html | 173 + test/oaassist/WpsOAAssist/index.html | 5 + test/oaassist/WpsOAAssist/js/common/common.js | 535 ++++ test/oaassist/WpsOAAssist/js/common/enum.js | 115 + .../WpsOAAssist/js/common/func_docEvents.js | 232 ++ .../WpsOAAssist/js/common/func_docProcess.js | 904 ++++++ .../WpsOAAssist/js/common/func_oastarter.js | 146 + .../WpsOAAssist/js/common/func_tabcontrol.js | 1431 +++++++++ test/oaassist/WpsOAAssist/js/common/time.js | 157 + test/oaassist/WpsOAAssist/js/main.js | 12 + .../oaassist/WpsOAAssist/otherslib/lib/formdata.js | 37 + .../WpsOAAssist/otherslib/lib/jquery.min.js | 6 + .../WpsOAAssist/otherslib/lib/qrcode.min.js | 1 + test/oaassist/WpsOAAssist/otherslib/lib/vue.min.js | 6 + test/oaassist/WpsOAAssist/package.json | 12 + test/oaassist/WpsOAAssist/redhead.html | 142 + test/oaassist/WpsOAAssist/ribbon.xml | 148 + test/oaassist/WpsOAAssist/selectBookmark.html | 195 ++ test/oaassist/WpsOAAssist/selectSeal.html | 205 ++ test/oaassist/WpsOAAssist/setUserName.html | 34 + test/oaassist/WpsOAAssist/taskpane.html | 143 + .../WpsOAAssist/template/OA模板公章.png | Bin 0 -> 10207 bytes test/oaassist/WpsOAAssist/template/模板.docx | Bin 0 -> 11755 bytes .../WpsOAAssist/template/红头文件.docx | Bin 0 -> 13608 bytes test/oaassist/server/.gitignore | 4 + test/oaassist/server/StartupServer.js | 310 ++ test/oaassist/server/package.json | 23 + test/oaassist/server/wwwroot/.gitignore | 2 + test/oaassist/server/wwwroot/LICENSE | 25 + test/oaassist/server/wwwroot/README.md | 17 + test/oaassist/server/wwwroot/demo.html | 208 ++ .../oaassist/server/wwwroot/file/HelloServlet.java | 140 + .../server/wwwroot/file/OA模板公章.png | Bin 0 -> 10207 bytes .../oaassist/server/wwwroot/file/templateData.json | 22 + test/oaassist/server/wwwroot/file/公文样章.wps | Bin 0 -> 35342 bytes test/oaassist/server/wwwroot/file/样章.docx | Bin 0 -> 15700 bytes test/oaassist/server/wwwroot/file/样章.pptx | Bin 0 -> 63515 bytes test/oaassist/server/wwwroot/file/样章.xlsx | Bin 0 -> 13971 bytes test/oaassist/server/wwwroot/file/样章2.docx | Bin 0 -> 11755 bytes .../oaassist/server/wwwroot/file/红头文件.docx | Bin 0 -> 13608 bytes test/oaassist/server/wwwroot/index.html | 40 + test/oaassist/server/wwwroot/jsplugins.xml | 18 + test/oaassist/server/wwwroot/resource/WPS.png | Bin 0 -> 9381 bytes test/oaassist/server/wwwroot/resource/css/demo.css | 71 + test/oaassist/server/wwwroot/resource/et.html | 53 + .../wwwroot/resource/highlight/highlight.pack.js | 3319 ++++++++++++++++++++ .../server/wwwroot/resource/highlight/zenburn.css | 115 + test/oaassist/server/wwwroot/resource/js/demo.js | 226 ++ test/oaassist/server/wwwroot/resource/js/et.js | 237 ++ .../server/wwwroot/resource/js/utils/json2.js | 433 +++ test/oaassist/server/wwwroot/resource/js/wpp.js | 238 ++ test/oaassist/server/wwwroot/resource/js/wps.js | 924 ++++++ .../oaassist/server/wwwroot/resource/js/wps_sdk.js | 957 ++++++ .../server/wwwroot/resource/js/wpsjsrpcsdk.js | 1355 ++++++++ test/oaassist/server/wwwroot/resource/wpp.html | 55 + test/oaassist/server/wwwroot/resource/wps.html | 67 + 242 files changed, 16779 insertions(+), 16779 deletions(-) delete mode 100644 oaassist/.gitignore delete mode 100644 oaassist/EtOAAssist/LICENSE delete mode 100644 oaassist/EtOAAssist/README.md delete mode 100644 oaassist/EtOAAssist/icon/w_Save.png delete mode 100644 oaassist/EtOAAssist/icon/w_SaveAs.png delete mode 100644 oaassist/EtOAAssist/index.html delete mode 100644 oaassist/EtOAAssist/js/common/common.js delete mode 100644 oaassist/EtOAAssist/js/common/func_docEvents.js delete mode 100644 oaassist/EtOAAssist/js/common/func_docProcess.js delete mode 100644 oaassist/EtOAAssist/js/common/func_oastarter.js delete mode 100644 oaassist/EtOAAssist/js/common/func_tabcontrol.js delete mode 100644 oaassist/EtOAAssist/js/main.js delete mode 100644 oaassist/EtOAAssist/package.json delete mode 100644 oaassist/EtOAAssist/ribbon.xml delete mode 100644 oaassist/README.md delete mode 100644 oaassist/WppOAAssist/LICENSE delete mode 100644 oaassist/WppOAAssist/README.md delete mode 100644 oaassist/WppOAAssist/icon/w_Save.png delete mode 100644 oaassist/WppOAAssist/icon/w_SaveAs.png delete mode 100644 oaassist/WppOAAssist/index.html delete mode 100644 oaassist/WppOAAssist/js/common/common.js delete mode 100644 oaassist/WppOAAssist/js/common/func_docEvents.js delete mode 100644 oaassist/WppOAAssist/js/common/func_docProcess.js delete mode 100644 oaassist/WppOAAssist/js/common/func_oastarter.js delete mode 100644 oaassist/WppOAAssist/js/common/func_tabcontrol.js delete mode 100644 oaassist/WppOAAssist/js/main.js delete mode 100644 oaassist/WppOAAssist/package.json delete mode 100644 oaassist/WppOAAssist/ribbon.xml delete mode 100644 oaassist/WpsOAAssist/LICENSE delete mode 100644 oaassist/WpsOAAssist/QRCode.html delete mode 100644 oaassist/WpsOAAssist/README.md delete mode 100644 oaassist/WpsOAAssist/icon/3.svg delete mode 100644 oaassist/WpsOAAssist/icon/c_bookmark.png delete mode 100644 oaassist/WpsOAAssist/icon/c_default.png delete mode 100644 oaassist/WpsOAAssist/icon/c_printDoc.png delete mode 100644 oaassist/WpsOAAssist/icon/c_seal.png delete mode 100644 oaassist/WpsOAAssist/icon/newFromTemp.svg delete mode 100644 oaassist/WpsOAAssist/icon/w_AcceptRev.png delete mode 100644 oaassist/WpsOAAssist/icon/w_BackDoc.png delete mode 100644 oaassist/WpsOAAssist/icon/w_CloseRev.png delete mode 100644 oaassist/WpsOAAssist/icon/w_CloseRev1 (2).png delete mode 100644 oaassist/WpsOAAssist/icon/w_CloseRev3.png delete mode 100644 oaassist/WpsOAAssist/icon/w_DeleteRev.png delete mode 100644 oaassist/WpsOAAssist/icon/w_DocClear.png delete mode 100644 oaassist/WpsOAAssist/icon/w_DocClound.png delete mode 100644 oaassist/WpsOAAssist/icon/w_DocOFD.png delete mode 100644 oaassist/WpsOAAssist/icon/w_DocQr.png delete mode 100644 oaassist/WpsOAAssist/icon/w_DocQr1.png delete mode 100644 oaassist/WpsOAAssist/icon/w_DocRevis.png delete mode 100644 oaassist/WpsOAAssist/icon/w_DocUOF.png delete mode 100644 oaassist/WpsOAAssist/icon/w_GovDoc.png delete mode 100644 oaassist/WpsOAAssist/icon/w_ImportDoc.png delete mode 100644 oaassist/WpsOAAssist/icon/w_ImportDoc1.png delete mode 100644 oaassist/WpsOAAssist/icon/w_InsDate.png delete mode 100644 oaassist/WpsOAAssist/icon/w_InsPicture.png delete mode 100644 oaassist/WpsOAAssist/icon/w_InsPictures.png delete mode 100644 oaassist/WpsOAAssist/icon/w_OpenRev.png delete mode 100644 oaassist/WpsOAAssist/icon/w_OpenRev2.png delete mode 100644 oaassist/WpsOAAssist/icon/w_PDF.png delete mode 100644 oaassist/WpsOAAssist/icon/w_PageGear.png delete mode 100644 oaassist/WpsOAAssist/icon/w_RejectRev.png delete mode 100644 oaassist/WpsOAAssist/icon/w_Save.png delete mode 100644 oaassist/WpsOAAssist/icon/w_SaveAs.png delete mode 100644 oaassist/WpsOAAssist/icon/w_Scanner16.png delete mode 100644 oaassist/WpsOAAssist/icon/w_WPSCloud.png delete mode 100644 oaassist/WpsOAAssist/importTemplate.html delete mode 100644 oaassist/WpsOAAssist/index.html delete mode 100644 oaassist/WpsOAAssist/js/common/common.js delete mode 100644 oaassist/WpsOAAssist/js/common/enum.js delete mode 100644 oaassist/WpsOAAssist/js/common/func_docEvents.js delete mode 100644 oaassist/WpsOAAssist/js/common/func_docProcess.js delete mode 100644 oaassist/WpsOAAssist/js/common/func_oastarter.js delete mode 100644 oaassist/WpsOAAssist/js/common/func_tabcontrol.js delete mode 100644 oaassist/WpsOAAssist/js/common/time.js delete mode 100644 oaassist/WpsOAAssist/js/main.js delete mode 100644 oaassist/WpsOAAssist/otherslib/lib/formdata.js delete mode 100644 oaassist/WpsOAAssist/otherslib/lib/jquery.min.js delete mode 100644 oaassist/WpsOAAssist/otherslib/lib/qrcode.min.js delete mode 100644 oaassist/WpsOAAssist/otherslib/lib/vue.min.js delete mode 100644 oaassist/WpsOAAssist/package.json delete mode 100644 oaassist/WpsOAAssist/redhead.html delete mode 100644 oaassist/WpsOAAssist/ribbon.xml delete mode 100644 oaassist/WpsOAAssist/selectBookmark.html delete mode 100644 oaassist/WpsOAAssist/selectSeal.html delete mode 100644 oaassist/WpsOAAssist/setUserName.html delete mode 100644 oaassist/WpsOAAssist/taskpane.html delete mode 100644 oaassist/WpsOAAssist/template/OA模板公章.png delete mode 100644 oaassist/WpsOAAssist/template/模板.docx delete mode 100644 oaassist/WpsOAAssist/template/红头文件.docx delete mode 100644 oaassist/server/.gitignore delete mode 100644 oaassist/server/StartupServer.js delete mode 100644 oaassist/server/package.json delete mode 100644 oaassist/server/wwwroot/.gitignore delete mode 100644 oaassist/server/wwwroot/LICENSE delete mode 100644 oaassist/server/wwwroot/README.md delete mode 100644 oaassist/server/wwwroot/demo.html delete mode 100644 oaassist/server/wwwroot/file/HelloServlet.java delete mode 100644 oaassist/server/wwwroot/file/OA模板公章.png delete mode 100644 oaassist/server/wwwroot/file/templateData.json delete mode 100644 oaassist/server/wwwroot/file/公文样章.wps delete mode 100644 oaassist/server/wwwroot/file/样章.docx delete mode 100644 oaassist/server/wwwroot/file/样章.pptx delete mode 100644 oaassist/server/wwwroot/file/样章.xlsx delete mode 100644 oaassist/server/wwwroot/file/样章2.docx delete mode 100644 oaassist/server/wwwroot/file/红头文件.docx delete mode 100644 oaassist/server/wwwroot/index.html delete mode 100644 oaassist/server/wwwroot/jsplugins.xml delete mode 100644 oaassist/server/wwwroot/resource/WPS.png delete mode 100644 oaassist/server/wwwroot/resource/css/demo.css delete mode 100644 oaassist/server/wwwroot/resource/et.html delete mode 100644 oaassist/server/wwwroot/resource/highlight/highlight.pack.js delete mode 100644 oaassist/server/wwwroot/resource/highlight/zenburn.css delete mode 100644 oaassist/server/wwwroot/resource/js/demo.js delete mode 100644 oaassist/server/wwwroot/resource/js/et.js delete mode 100644 oaassist/server/wwwroot/resource/js/utils/json2.js delete mode 100644 oaassist/server/wwwroot/resource/js/wpp.js delete mode 100644 oaassist/server/wwwroot/resource/js/wps.js delete mode 100644 oaassist/server/wwwroot/resource/js/wps_sdk.js delete mode 100644 oaassist/server/wwwroot/resource/js/wpsjsrpcsdk.js delete mode 100644 oaassist/server/wwwroot/resource/wpp.html delete mode 100644 oaassist/server/wwwroot/resource/wps.html create mode 100644 test/oaassist/.gitignore create mode 100644 test/oaassist/EtOAAssist/LICENSE create mode 100644 test/oaassist/EtOAAssist/README.md create mode 100644 test/oaassist/EtOAAssist/icon/w_Save.png create mode 100644 test/oaassist/EtOAAssist/icon/w_SaveAs.png create mode 100644 test/oaassist/EtOAAssist/index.html create mode 100644 test/oaassist/EtOAAssist/js/common/common.js create mode 100644 test/oaassist/EtOAAssist/js/common/func_docEvents.js create mode 100644 test/oaassist/EtOAAssist/js/common/func_docProcess.js create mode 100644 test/oaassist/EtOAAssist/js/common/func_oastarter.js create mode 100644 test/oaassist/EtOAAssist/js/common/func_tabcontrol.js create mode 100644 test/oaassist/EtOAAssist/js/main.js create mode 100644 test/oaassist/EtOAAssist/package.json create mode 100644 test/oaassist/EtOAAssist/ribbon.xml create mode 100644 test/oaassist/README.md create mode 100644 test/oaassist/WppOAAssist/LICENSE create mode 100644 test/oaassist/WppOAAssist/README.md create mode 100644 test/oaassist/WppOAAssist/icon/w_Save.png create mode 100644 test/oaassist/WppOAAssist/icon/w_SaveAs.png create mode 100644 test/oaassist/WppOAAssist/index.html create mode 100644 test/oaassist/WppOAAssist/js/common/common.js create mode 100644 test/oaassist/WppOAAssist/js/common/func_docEvents.js create mode 100644 test/oaassist/WppOAAssist/js/common/func_docProcess.js create mode 100644 test/oaassist/WppOAAssist/js/common/func_oastarter.js create mode 100644 test/oaassist/WppOAAssist/js/common/func_tabcontrol.js create mode 100644 test/oaassist/WppOAAssist/js/main.js create mode 100644 test/oaassist/WppOAAssist/package.json create mode 100644 test/oaassist/WppOAAssist/ribbon.xml create mode 100644 test/oaassist/WpsOAAssist/LICENSE create mode 100644 test/oaassist/WpsOAAssist/QRCode.html create mode 100644 test/oaassist/WpsOAAssist/README.md create mode 100644 test/oaassist/WpsOAAssist/icon/3.svg create mode 100644 test/oaassist/WpsOAAssist/icon/c_bookmark.png create mode 100644 test/oaassist/WpsOAAssist/icon/c_default.png create mode 100644 test/oaassist/WpsOAAssist/icon/c_printDoc.png create mode 100644 test/oaassist/WpsOAAssist/icon/c_seal.png create mode 100644 test/oaassist/WpsOAAssist/icon/newFromTemp.svg create mode 100644 test/oaassist/WpsOAAssist/icon/w_AcceptRev.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_BackDoc.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_CloseRev.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_CloseRev1 (2).png create mode 100644 test/oaassist/WpsOAAssist/icon/w_CloseRev3.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_DeleteRev.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_DocClear.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_DocClound.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_DocOFD.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_DocQr.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_DocQr1.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_DocRevis.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_DocUOF.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_GovDoc.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_ImportDoc.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_ImportDoc1.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_InsDate.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_InsPicture.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_InsPictures.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_OpenRev.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_OpenRev2.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_PDF.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_PageGear.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_RejectRev.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_Save.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_SaveAs.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_Scanner16.png create mode 100644 test/oaassist/WpsOAAssist/icon/w_WPSCloud.png create mode 100644 test/oaassist/WpsOAAssist/importTemplate.html create mode 100644 test/oaassist/WpsOAAssist/index.html create mode 100644 test/oaassist/WpsOAAssist/js/common/common.js create mode 100644 test/oaassist/WpsOAAssist/js/common/enum.js create mode 100644 test/oaassist/WpsOAAssist/js/common/func_docEvents.js create mode 100644 test/oaassist/WpsOAAssist/js/common/func_docProcess.js create mode 100644 test/oaassist/WpsOAAssist/js/common/func_oastarter.js create mode 100644 test/oaassist/WpsOAAssist/js/common/func_tabcontrol.js create mode 100644 test/oaassist/WpsOAAssist/js/common/time.js create mode 100644 test/oaassist/WpsOAAssist/js/main.js create mode 100644 test/oaassist/WpsOAAssist/otherslib/lib/formdata.js create mode 100644 test/oaassist/WpsOAAssist/otherslib/lib/jquery.min.js create mode 100644 test/oaassist/WpsOAAssist/otherslib/lib/qrcode.min.js create mode 100644 test/oaassist/WpsOAAssist/otherslib/lib/vue.min.js create mode 100644 test/oaassist/WpsOAAssist/package.json create mode 100644 test/oaassist/WpsOAAssist/redhead.html create mode 100644 test/oaassist/WpsOAAssist/ribbon.xml create mode 100644 test/oaassist/WpsOAAssist/selectBookmark.html create mode 100644 test/oaassist/WpsOAAssist/selectSeal.html create mode 100644 test/oaassist/WpsOAAssist/setUserName.html create mode 100644 test/oaassist/WpsOAAssist/taskpane.html create mode 100644 test/oaassist/WpsOAAssist/template/OA模板公章.png create mode 100644 test/oaassist/WpsOAAssist/template/模板.docx create mode 100644 test/oaassist/WpsOAAssist/template/红头文件.docx create mode 100644 test/oaassist/server/.gitignore create mode 100644 test/oaassist/server/StartupServer.js create mode 100644 test/oaassist/server/package.json create mode 100644 test/oaassist/server/wwwroot/.gitignore create mode 100644 test/oaassist/server/wwwroot/LICENSE create mode 100644 test/oaassist/server/wwwroot/README.md create mode 100644 test/oaassist/server/wwwroot/demo.html create mode 100644 test/oaassist/server/wwwroot/file/HelloServlet.java create mode 100644 test/oaassist/server/wwwroot/file/OA模板公章.png create mode 100644 test/oaassist/server/wwwroot/file/templateData.json create mode 100644 test/oaassist/server/wwwroot/file/公文样章.wps create mode 100644 test/oaassist/server/wwwroot/file/样章.docx create mode 100644 test/oaassist/server/wwwroot/file/样章.pptx create mode 100644 test/oaassist/server/wwwroot/file/样章.xlsx create mode 100644 test/oaassist/server/wwwroot/file/样章2.docx create mode 100644 test/oaassist/server/wwwroot/file/红头文件.docx create mode 100644 test/oaassist/server/wwwroot/index.html create mode 100644 test/oaassist/server/wwwroot/jsplugins.xml create mode 100644 test/oaassist/server/wwwroot/resource/WPS.png create mode 100644 test/oaassist/server/wwwroot/resource/css/demo.css create mode 100644 test/oaassist/server/wwwroot/resource/et.html create mode 100644 test/oaassist/server/wwwroot/resource/highlight/highlight.pack.js create mode 100644 test/oaassist/server/wwwroot/resource/highlight/zenburn.css create mode 100644 test/oaassist/server/wwwroot/resource/js/demo.js create mode 100644 test/oaassist/server/wwwroot/resource/js/et.js create mode 100644 test/oaassist/server/wwwroot/resource/js/utils/json2.js create mode 100644 test/oaassist/server/wwwroot/resource/js/wpp.js create mode 100644 test/oaassist/server/wwwroot/resource/js/wps.js create mode 100644 test/oaassist/server/wwwroot/resource/js/wps_sdk.js create mode 100644 test/oaassist/server/wwwroot/resource/js/wpsjsrpcsdk.js create mode 100644 test/oaassist/server/wwwroot/resource/wpp.html create mode 100644 test/oaassist/server/wwwroot/resource/wps.html diff --git a/oaassist/.gitignore b/oaassist/.gitignore deleted file mode 100644 index 0076954..0000000 --- a/oaassist/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# WPS加载项快速上手说明源文件忽略 -/WPS加载项快速上手说明/ \ No newline at end of file diff --git a/oaassist/EtOAAssist/LICENSE b/oaassist/EtOAAssist/LICENSE deleted file mode 100644 index 3417144..0000000 --- a/oaassist/EtOAAssist/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ - -Copyright @ 2012-2019, Kingsoft office,All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -2. 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. -3. Neither the name of the copyright holder 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 HOLDER 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. \ No newline at end of file diff --git a/oaassist/EtOAAssist/README.md b/oaassist/EtOAAssist/README.md deleted file mode 100644 index 490a26a..0000000 --- a/oaassist/EtOAAssist/README.md +++ /dev/null @@ -1,19 +0,0 @@ -## Welcome to ET OAAssist Demo - -### 这个项目是什么? - -这个工程为WPS表格项目一个简单的OA场景集成的WPS加载项——OA助手,旨在帮助大家能够快速理解并熟悉WPS加载项机制以及和浏览器调用交互的流程。 - -### 工程结构 - -* icon 图标文件。 -* js WPS 加载项功能逻辑的js代码。 -* index.html 加载项的默认加载页面。 -* ribbon.xml 自定义选项卡配置。 - -### 注意事项 - -* 本工程只是演示demo -* 我们建议您结合具体的应用场景修改示例代码,这样更能够体现OA助手集成的应用场景 -* 为了保护代码,建议代码上线前进行混淆 -* 使用该工程的时候,必须要安装WPS专业版,请咨询QQ:3253920855 diff --git a/oaassist/EtOAAssist/icon/w_Save.png b/oaassist/EtOAAssist/icon/w_Save.png deleted file mode 100644 index edcd53adbae0b94fe56289cb590884a0a375d082..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13913 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 diff --git a/oaassist/EtOAAssist/icon/w_SaveAs.png b/oaassist/EtOAAssist/icon/w_SaveAs.png deleted file mode 100644 index a5fe456f5f79799d24e7d2b894dce9964ca1d6f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14246 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 M(kfEb5~iR352)qN@c;k- diff --git a/oaassist/EtOAAssist/index.html b/oaassist/EtOAAssist/index.html deleted file mode 100644 index 095b758..0000000 --- a/oaassist/EtOAAssist/index.html +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/oaassist/EtOAAssist/js/common/common.js b/oaassist/EtOAAssist/js/common/common.js deleted file mode 100644 index 7a13c95..0000000 --- a/oaassist/EtOAAssist/js/common/common.js +++ /dev/null @@ -1,229 +0,0 @@ -// -------------------------- 通用方法 --------------------------- -//扩展js string endwith,startwith方法 -String.prototype.endWith = function (str) { - if (str == null || str == "" || this.length == 0 || str.length > this.length) - return false; - if (this.substring(this.length - str.length) == str) - return true; - else - return false; -} - -String.prototype.startWith = function (str) { - if (str == null || str == "" || this.length == 0 || str.length > this.length) - return false; - if (this.substr(0, str.length) == str) - return true; - else - return false; -} - -//UTF-16转UTF-8 -function utf16ToUtf8(s) { - if (!s) { - return; - } - var i, code, ret = [], - len = s.length; - for (i = 0; i < len; i++) { - code = s.charCodeAt(i); - if (code > 0x0 && code <= 0x7f) { - //单字节 - //UTF-16 0000 - 007F - //UTF-8 0xxxxxxx - ret.push(s.charAt(i)); - } else if (code >= 0x80 && code <= 0x7ff) { - //双字节 - //UTF-16 0080 - 07FF - //UTF-8 110xxxxx 10xxxxxx - ret.push( - //110xxxxx - String.fromCharCode(0xc0 | ((code >> 6) & 0x1f)), - //10xxxxxx - String.fromCharCode(0x80 | (code & 0x3f)) - ); - } else if (code >= 0x800 && code <= 0xffff) { - //三字节 - //UTF-16 0800 - FFFF - //UTF-8 1110xxxx 10xxxxxx 10xxxxxx - ret.push( - //1110xxxx - String.fromCharCode(0xe0 | ((code >> 12) & 0xf)), - //10xxxxxx - String.fromCharCode(0x80 | ((code >> 6) & 0x3f)), - //10xxxxxx - String.fromCharCode(0x80 | (code & 0x3f)) - ); - } - } - return ret.join(''); -} - -//若要显示:当前日期加时间(如:200906121200) -function currentTime() { - var now = new Date(); - - var year = now.getFullYear(); //年 - var month = now.getMonth() + 1; //月 - var day = now.getDate(); //日 - - var hh = now.getHours(); //时 - var mm = now.getMinutes(); //分 - - var clock = year + ""; - - if (month < 10) - clock += "0"; - - clock += month + ""; - - if (day < 10) - clock += "0"; - - clock += day + ""; - - if (hh < 10) - clock += "0"; - - clock += hh + ""; - if (mm < 10) clock += '0'; - clock += mm; - return (clock); -} - -/** - * 判断文件个数是否为0,若为0则关闭 - * @param {*} name - */ -function closeEtIfNoDocument() { - var etApp = wps.EtApplication(); - var docs = etApp.Workbooks; - if (docs && docs.Count == 0) { - etApp.Quit(); - } -} - -function activeTab() { - wps.ribbonUI.ActivateTab('WPSWorkExtTab'); -} - -function showOATab() { - wps.PluginStorage.setItem("ShowOATabDocActive", pCheckIfOADoc()); //根据文件是否为OA文件来显示OA菜单 - wps.ribbonUI.Invalidate(); // 刷新Ribbon自定义按钮的状态 -} - -function pGetParamName(data, attr) { - var start = data.indexOf(attr); - data = data.substring(start + attr.length); - return data; -} - -/** - * 从requst中获取文件名(确保请求中有filename这个参数) - * @param {*} request - * @param {*} url - */ - function pGetFileName(request, url) { - var disposition = request.getResponseHeader("Content-Disposition"); - var filename = ""; - if (disposition) { - var matchs = pGetParamName(disposition, "filename="); - if (matchs) { - filename = decodeURIComponent(matchs); - } else { - filename = "petro" + Date.getTime(); - } - } else { - filename = url.substring(url.lastIndexOf("/") + 1); - filename=filename.split("?")[0] - } - return filename; -} - -function StringToUint8Array(string) { - var binLen, buffer, chars, i, _i; - binLen = string.length; - buffer = new ArrayBuffer(binLen); - chars = new Uint8Array(buffer); - for (var i = 0; i < binLen; ++i) { - chars[i] = String.prototype.charCodeAt.call(string, i); - } - return buffer; -} - -function DownloadFile(url, callback) { - // 需要根据业务实现一套 - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function () { - if (this.readyState == 4 && this.status == 200) { - var path = wps.Env.GetTempPath() + "/" + pGetFileName(xhr, url); - var reader = new FileReader(); - reader.onload = function () { - wps.FileSystem.writeAsBinaryString(path, reader.result); - callback(path); - }; - reader.readAsBinaryString(xhr.response); - } - } - xhr.open('GET', url); - xhr.responseType = 'blob'; - xhr.send(); -} - -function UploadFile(strFileName, strPath, uploadPath, strFieldName, OnSuccess, OnFail) { - var xhr = new XMLHttpRequest(); - xhr.open('POST', uploadPath); - - function KFormData() { - this.fake = true; - this.boundary = "--------FormData" + Math.random(); - this._fields = []; - } - KFormData.prototype.append = function (key, value) { - this._fields.push([key, value]); - } - KFormData.prototype.toString = function () { - var boundary = this.boundary; - var body = ""; - this._fields.forEach(function (field) { - body += "--" + boundary + "\r\n"; - if (field[1].name) { - var file = field[1]; - body += "Content-Disposition: form-data; name=\"" + field[0] + "\"; filename=\"" + file.name + "\"\r\n"; - body += "Content-Type: " + file.type + "\r\n\r\n"; - body += file.getAsBinary() + "\r\n"; - } else { - body += "Content-Disposition: form-data; name=\"" + field[0] + "\";\r\n\r\n"; - body += field[1] + "\r\n"; - } - }); - body += "--" + boundary + "--"; - return body; - } - var fileData = wps.FileSystem.readAsBinaryString(strPath); - var data = new KFormData(); - data.append('file', { - name: strFileName, - type: "application/octet-stream", - getAsBinary: function () { - return fileData; - } - }); - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status == 200) - OnSuccess(xhr.response) - else - OnFail(xhr.response); - } - }; - xhr.setRequestHeader("Cache-Control", "no-cache"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - if (data.fake) { - xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + data.boundary); - var arr = StringToUint8Array(data.toString()); - xhr.send(arr); - } else { - xhr.send(data); - } -} \ No newline at end of file diff --git a/oaassist/EtOAAssist/js/common/func_docEvents.js b/oaassist/EtOAAssist/js/common/func_docEvents.js deleted file mode 100644 index e8cb455..0000000 --- a/oaassist/EtOAAssist/js/common/func_docEvents.js +++ /dev/null @@ -1,251 +0,0 @@ -// 打印前监听事件 -function OnWorkbookBeforePrint(doc) { - return; -} - - -//切换窗口时触发的事件 -function OnWindowActivate() { - console.log("OnWindowActivate" + "======================="); - - var l_doc = wps.EtApplication().ActiveWorkbook; - SetCurrDocEnvProp(l_doc); // 设置当前文档对应的用户名 - showOATab(); // 根据文件是否为OA文件来显示OA菜单再进行刷新按钮 - setTimeout(activeTab, 2000); // 激活页面必须要页签显示出来,所以做1秒延迟 - return; -} - -/** - * 作用:判断OA文档是否被另存为了 - */ -function CheckIfOADocSaveAs(doc) { - if (!doc) { - return; - } - // 获取OA文档的原始保存路径 - var l_Path = GetDocParamsValue(doc, "SourcePath"); - // 原路径和当前文件的路径对比 - return l_Path == doc.FullName; -} - - -// 当文件保存前触发的事件 -function OnWorkbookBeforeSave(doc) { - console.log("OnWorkbookBeforeSave"); - - //设置变量,判断是否当前用户按了自定义的OA文件保存按钮 - var l_IsOADocButtonSave = false; - l_IsOADocButtonSave = wps.PluginStorage.getItem("OADocUserSave"); - - //根据传入参数判断当前文档是否能另存为,默认不能另存为 - if (pCheckCurrOADocCanSaveAs(doc) == false) { //先根据OA助手的默认设置判断是否允许OA文档另存为操作 - //如果配置文件:OA文档不允许另存为,则再判断 - //2、判断当前OA文档是否不落地文档 - if (pIsOnlineOADoc(doc) == true) { - //如果是不落地文档,则判断是否是系统正在保存 - if (l_IsOADocButtonSave == false) { - alert("来自OA的不落地文档,禁止另存为本地文档!"); - //如果是OA文档,则禁止另存为 - wps.ApiEvent.Cancel = true; - } - } else { - //这里要再判断OA文档是否被用户另存为 - if (l_IsOADocButtonSave == false) { - doc.Save(); //直接保存本地就行 - //如果是OA文档,则禁止另存为 - wps.ApiEvent.Cancel = true; - } else {} - } - - } - - //保存文档后,也要刷新一下Ribbon按钮的状态 - showOATab(); - return; -} - - -//文档保存前关闭事件 -/** - * 作用: - * @param {*} doc - */ -function OnWorkbookBeforeClose(doc) { - console.log('OnWorkbookBeforeClose'); - - var l_fullName = doc.FullName; - var l_bIsOADoc = false; - l_bIsOADoc = CheckIfDocIsOADoc(doc); //判断是否OA文档要关闭 - if (l_bIsOADoc == false) { // 非OA文档不做处理 - return; - } - //判断是否只读的文档,或受保护的文档,对于只读的文档,不给予保存提示 - if (pISOADocReadOnly(doc) == false) { - if (doc.Saved == false) { //如果OA文档关闭前,有未保存的数据 - if (wps.confirm("系统文件有改动,是否提交后关闭?" + "\n" + "确认后请按上传按钮执行上传操作。取消则继续关闭文档。")) { - wps.ApiEvent.Cancel = true; - return; - } - } - } - doc.Close(false); //保存待定的更改。 - closeEtIfNoDocument(); // 判断文件个数是否为0,若为0则关闭组件 - wps.FileSystem.Remove(l_fullName); -} - - -//文档保存后关闭事件 -function OnWorkbookAfterClose(doc) { - console.log("OnWorkbookAfterClose"); - - var l_NofityURL = GetDocParamsValue(doc, "notifyUrl"); - if (l_NofityURL) { - l_NofityURL = l_NofityURL.replace("{?}", "3"); //约定:参数为3则文档关闭 - console.log("" + l_NofityURL); - NotifyToServer(l_NofityURL); - } - - pRemoveDocParam(doc); // 关闭文档时,移除PluginStorage对象的参数 - pSetetAppUserName(); // 判断文档关闭后,如果系统已经没有打开的文档了,则设置回初始用户名 -} - -//文档打开事件 -function OnWorkbookOpen(doc) { - //设置当前新增文档是否来自OA的文档 - // if (wps.PluginStorage.getItem("IsInCurrOADocOpen") == false) { - // //如果是用户自己在WPS环境打开文档,则设置非OA文档标识 - // pSetNoneOADocFlag(doc); - // } - - OnWindowActivate(); - ChangeOATabOnDocOpen(); //打开文档后,默认打开Tab页 -} - -//新建文档事件 -function OnWorkbookNew(doc) { - //设置当前新增文档是否来自OA的文档 - // if (wps.PluginStorage.getItem("IsInCurrOADocOpen") == false) { - // //如果是用户自己在WPS环境打开文档,则设置非OA文档标识 - // pSetNoneOADocFlag(doc); - // } - ChangeOATabOnDocOpen(); // 打开OA助手Tab菜单页 - wps.ribbonUI.Invalidate(); // 刷新Ribbon按钮的状态 -} - - -/** - * 作用:判断当前文档是否是只读文档 - * 返回值:布尔 - */ -function pISOADocReadOnly(doc) { - if (!doc) { - return false; - } - var l_openType = GetDocParamsValue(doc, "openType"); // 获取OA传入的参数 openType - if (l_openType == "") { - return false; - } - try { - if (!!l_openType.protectType) { - return true; - } // 保护 - } catch (err) { - return false; - } -} - - -/** - * 作用:根据当前活动文档的情况判断,当前文档适用的系统参数,例如:当前文档对应的用户名称等 - */ -function SetCurrDocEnvProp(doc) { - if (!doc) return; - var l_bIsOADoc = false; - l_bIsOADoc = pCheckIfOADoc(doc); - - //如果是OA文件,则按OA传来的用户名设置WPS OA助手WPS用户名设置按钮冲突 - if (l_bIsOADoc == true) { - var l_userName = GetDocParamsValue(doc, "userName"); - if (l_userName != "") { - wps.EtApplication().UserName = l_userName; - return; - } - } - //如果是非OA文件或者参数的值是空值,则按WPS安装默认用户名设置 - wps.EtApplication().UserName = wps.PluginStorage.getItem("WPSInitUserName"); -} - -/* - 入口参数:doc - 功能说明:判断当前文档是否能另存为本地文件 - 返回值:布尔值true or false -*/ -function pCheckCurrOADocCanSaveAs(doc) { - //如果是非OA文档,则允许另存为 - if (CheckIfDocIsOADoc(doc) == false) return true; - - //对于来自OA系统的文档,则获取该文档对应的属性参数 - var l_CanSaveAs = GetDocParamsValue(doc, "CanSaveAs"); - - //判断OA传入的参数 - if (typeof (l_CanSaveAs) == "boolean") { - return l_CanSaveAs; - } - return false; -} - -/** - * 作用:判断文档关闭后,如果系统已经没有打开的文档了,则设置回初始用户名 - */ -function pSetetAppUserName() { - //文档全部关闭的情况下,把WPS初始启动的用户名设置回去 - if (wps.EtApplication().Workbooks.Count == 1) { - var l_strUserName = wps.PluginStorage.getItem("WPSInitUserName"); - wps.EtApplication().UserName = l_strUserName; - } -} - -/** - * 作用:文档关闭后,删除对应的PluginStorage内的参数信息 - * 返回值:没有返回值 - * @param {*} doc - */ -function pRemoveDocParam(doc) { - if (!doc) return; - wps.PluginStorage.removeItem(doc.FullName); - return; -} - -/** - * 作用:判断当前文档是否从OA来的文档,如果非OA文档(就是本地新建或打开的文档,则设置EnumOAFlag 标识) - * 作用:设置非OA文档的标识状态 - * @param {*} doc - * 返回值:无 - */ -function pSetNoneOADocFlag(doc) { - if (!doc) return; - var l_param = wps.PluginStorage.getItem(doc.FullName); //定义JSON文档参数 - var l_objParams = new Object(); - if (l_param) { - l_objParams = JSON.parse(l_param); - } - l_objParams.isOA = EnumOAFlag.DocFromNoOA; // 新增非OA打开文档属性 - wps.PluginStorage.setItem(doc.FullName, JSON.stringify(l_objParams)); // 存入内存中 -} - - -/** - * 作用:根据设置判断打开文件是否默认激活OA助手工具Tab菜单 - * 返回值:无 - */ -function ChangeOATabOnDocOpen() { - var l_ShowOATab = true; //默认打开 - l_ShowOATab = wps.PluginStorage.getItem("ShowOATabDocActive"); - - if (l_ShowOATab == true) { - if (wps.ribbonUI) - wps.ribbonUI.ActivateTab("WPSWorkExtTab"); //新建文档时,自动切换到OA助手状态 - else - wps.ActivateTab("WPSWorkExtTab"); //新建文档时,自动切换到OA助手状态 - } -} \ No newline at end of file diff --git a/oaassist/EtOAAssist/js/common/func_docProcess.js b/oaassist/EtOAAssist/js/common/func_docProcess.js deleted file mode 100644 index f7a77bc..0000000 --- a/oaassist/EtOAAssist/js/common/func_docProcess.js +++ /dev/null @@ -1,354 +0,0 @@ -/** - * 从OA调用传来的指令,打开本地新建文件 - * @param {*} fileUrl 文件url路径 - */ -function NewFile(params) { - //获取ET Application 对象 - var etApp = wps.EtApplication(); - wps.PluginStorage.setItem("IsInCurrOADocOpen", true); //设置OA打开文档的临时状态 - var doc = etApp.Workbooks.Add(); //新增OA端文档 - wps.PluginStorage.setItem("IsInCurrOADocOpen", false); - - //检查系统临时文件目录是否能访问 - if (wps.Env && wps.Env.GetTempPath) { - if (params.newFileName) { - //按OA传入的文件名称保存 - doc.SaveAs($FileName = wps.Env.GetTempPath() + "/" + params.newFileName, undefined, undefined, undefined, undefined, undefined, undefined, undefined, false); - } else { - //OA传入空文件名称,则保存成系统时间文件 - doc.SaveAs($FileName = wps.Env.GetTempPath() + "/OA_" + currentTime(), undefined, undefined, undefined, undefined, undefined, undefined, undefined, false); - } - } else { - alert("文档保存临时目录出错!不能保存新建文档!请联系系统开发商。"); - } - - var l_NofityURL = GetParamsValue(params, "notifyUrl"); - if (l_NofityURL) { - NotifyToServer(l_NofityURL.replace("{?}", "1")); - } - - //Office文件打开后,设置该文件属性:从服务端来的OA文件 - pSetOADocumentFlag(doc, params); - //设置当前文档为 本地磁盘落地模式 - DoSetOADocLandMode(doc, EnumDocLandMode.DLM_LocalDoc); - //强制执行一次Activate事件 - OnWindowActivate(); - - return doc; //返回新创建的Document对象 -} - - -/** - * 打开服务器上的文件 - * @param {*} fileUrl 文件url路径 - */ -function OpenFile(params) { - var l_strFileUrl = params.fileName; //来自OA网页端的OA文件下载路径 - var doc; - var l_IsOnlineDoc = false; //默认打开的是不落地文档 - if (l_strFileUrl) { - //下载文档之前,判断是否已下载该文件 - if (pCheckIsExistOpenOADoc(l_strFileUrl) == true) { - //如果找到相同OA地址文档,则给予提示 - wps.EtApplication().Visible = true - //根据OA助手对是否允许再次打开相同文件的判断处理 - var l_AllowOADocReOpen = false; - l_AllowOADocReOpen = wps.PluginStorage.getItem("AllowOADocReOpen"); - if (l_AllowOADocReOpen == false) { - alert("已打开相同的OA文件,请关闭之前的文件,再次打开。"); - wps.EtApplication().Visible = true - return null; - } else { - //处理重复打开相同OA 文件的方法 - var nDocCount = wps.EtApplication().Workbooks.Count; - pReOpenOADoc(l_strFileUrl); - //重复打开的文档采用不落地的方式打开 - // 不落地方式打开文档判断落地比较多,V1版本先暂时关闭 - l_IsOnlineDoc = true; - var nDocCount_New = wps.EtApplication().Workbooks.Count; - if (nDocCount_New > nDocCount) { - doc = wps.EtApplication().ActiveWorkbook; - } - } - } else { - //如果当前没有打开文档,则另存为本地文件,再打开 - if (l_strFileUrl.startWith("http")) { // 网络文档 - DownloadFile(l_strFileUrl, function (path) { - if (path == "") { - alert("从服务端下载路径:" + l_strFileUrl + "\n" + "获取文件下载失败!"); - return null; - } - - doc = pDoOpenOADocProcess(params, path); - pOpenFile(doc, params, l_IsOnlineDoc); - }); - return null; - } else { //本地文档 - doc = pDoOpenOADocProcess(params, l_strFileUrl); - if (doc) - doc.SaveAs($FileName = wps.Env.GetTempPath() + "/" + doc.Name, undefined, undefined, undefined, undefined, undefined, undefined, undefined, false); - } - } - } else { - //fileURL 如果为空,则按新建OA本地文件处理 - NewFile(params); - } - - //如果打开pdf等其他非Office文档,则doc对象为空 - if (!doc) { - return null; - } - - pOpenFile(doc, params, l_IsOnlineDoc); - - return doc -} - -function pOpenFile(doc, params, isOnlineDoc) { - var l_IsOnlineDoc = isOnlineDoc - console.log(doc) - //Office文件打开后,设置该文件属性:从服务端来的OA文件 - pSetOADocumentFlag(doc, params); - //设置当前文档为 本地磁盘落地模式 - if (l_IsOnlineDoc == true) { - DoSetOADocLandMode(doc, EnumDocLandMode.DLM_OnlineDoc); - } else { - DoSetOADocLandMode(doc, EnumDocLandMode.DLM_LocalDoc); - } - - l_NofityURL = GetParamsValue(params, "notifyUrl"); - if (l_NofityURL) { - l_NofityURL = l_NofityURL.replace("{?}", "1"); //约定:参数为1则代码打开状态 - NotifyToServer(l_NofityURL); - } - //重新设置工具条按钮的显示状态 - pDoResetRibbonGroups(); - // 触发切换窗口事件 - OnWindowActivate(); - return doc; -} - -/** - * 文档打开服务器上的文件 - * @param {*} fileUrl 文件url路径 - */ -function OpenOnLineFile(OAParams) { - //OA参数如果为空的话退出 - if (!OAParams) return; - - //获取在线文档URL - var l_OAFileUrl = OAParams.fileName; - var l_doc; - if (l_OAFileUrl) { - //下载文档不落地(16版WPS的925后支持) - wps.PluginStorage.setItem("IsInCurrOADocOpen", true); - wps.EtApplication().Workbooks.OpenFromUrl(l_OAFileUrl, "OnOpenOnLineDocSuccess", "OnOpenOnLineDocDownFail"); - wps.PluginStorage.setItem("IsInCurrOADocOpen", false); - l_doc = wps.EtApplication().ActiveWorkbook; - } - - //Office文件打开后,设置该文件属性:从服务端来的OA文件 - pOpenFile(l_doc, OAParams, true); - return l_doc; -} - - -/** - * 打开在线文档成功后触发事件 - * @param {*} resp - */ -function OnOpenOnLineDocSuccess(resp) { - -} - - -/** - * 作用:打开文档处理的各种过程,包含:打开带密码的文档,保护方式打开文档,修订方式打开文档等种种情况 - * params Object OA Web端传来的请求JSON字符串,具体参数说明看下面数据 - * TempLocalFile : 字符串 先把文档从OA系统下载并保存在Temp临时目录,这个参数指已经下载下来的本地文档地址 - * ----------------------以下是OA参数的一些具体规范名称 - * docId String 文档ID - * uploadPath String 保存文档接口 - * fileName String 获取服务器文档接口(不传即为新建空文档) - * userName String 用于更改显示修改人的用户名 - * buttonGroups string 自定义按钮组 (可不传,不传显示所有按钮) - * openType String 文档打开方式 ,不传正常打开 - * protectType bool 文档保护类型,false或是未定义为不启用保护,其他为启用 - * password String密码 - */ -function pDoOpenOADocProcess(params, TempLocalFile) { - var l_ProtectType = false; //默认文档保护类型 0 为不启用保护 - var l_ProtectPassword = ""; //默认文档密码为空 - - var l_strDocPassword = ""; //打开文档密码参数 - - for (var key = "" in params) { - switch (key.toUpperCase()) // - { - case "userName".toUpperCase(): //修改当前文档用户名 - wps.EtApplication().UserName = params[key]; - break; - case "openType".toUpperCase(): - l_ProtectType = params[key].protectType; //获取OA传来的文档保护类型 - l_ProtectPassword = params[key].password; //获取OA传来的保护模式下的文档密码 - break; - case "buttonGroups".toUpperCase(): //按钮组合 - break; - case "docPassword".toUpperCase(): //传入打开文件的密码 - l_strDocPassword = params[key].docPassword; - break; - } - - } - - var l_Doc; - l_Doc = wps.EtApplication().Workbooks.Open(TempLocalFile, false, false, undefined, l_strDocPassword); - - //打开文档后,根据保护类型设置文档保护 - if (!!l_ProtectType) // 设置文档保护 - SetOADocProtect(l_Doc, l_ProtectPassword); - return l_Doc; -} - -/** - * protectType: '', 文档保护模式 - * @param {*} ProtectPassword - * @param {*} doc - */ -function SetOADocProtect(doc, ProtectPassword) { - if (!doc) return; //校验文档是否存在 - - // 保护文档如果之前有被保护,再次保护会出问题,需要先解除保护 - doc.Unprotect(); - doc.Protect(ProtectPassword); - return; -} - - -/** - * 打开在线不落地文档出现失败时,给予错误提示 - */ -function OnOpenOnLineDocDownFail() { - alert("打开在线不落地文档失败!请尝试重新打开。"); - return; -} - -/** - * 功能说明:判断是否已存在来自OA的已打开的文档 - * @param {字符串} FileURL - */ -function pCheckIsExistOpenOADoc(FileURL) { - var l_DocCount = wps.EtApplication().Workbooks.Count; - if (l_DocCount <= 0) return false; - - //轮询检查当前已打开的WPS文档中,是否存在OA相同的文件 - if (l_DocCount >= 1) { - for (var l_index = 1; l_index <= l_DocCount; l_index++) { - var l_objDoc = wps.EtApplication().Workbooks.Item(l_index); - - var l_strParam = wps.PluginStorage.getItem(l_objDoc.FullName); - if (l_strParam == null) - continue; - var l_objParam = JSON.parse(l_strParam) - if (l_objParam.fileName == FileURL) { - return true; - } - } - return false; - } -} - -/** - * 参数: - * doc : 当前OA文档的Document对象 - * DocLandMode : 落地模式设置 - */ -function DoSetOADocLandMode(doc, DocLandMode) { - if (!doc) return; - var l_Param = wps.PluginStorage.getItem(doc.FullName); - var l_objParam = JSON.parse(l_Param); - //增加属性,或设置 - l_objParam.OADocLandMode = DocLandMode; //设置OA文档的落地标志 - - var l_p = JSON.stringify(l_objParam); - //将OA文档落地模式标志存入系统变量对象保存 - - wps.PluginStorage.setItem(doc.FullName, l_p); - -} - -//Office文件打开后,设置该文件属性:从服务端来的OA文件 -function pSetOADocumentFlag(doc, params) { - if (!doc) { - return; - } - var l_Param = params; - l_Param.isOA = EnumOAFlag.DocFromOA; //设置OA打开文档的标志 - l_Param.SourcePath = doc.FullName; //保存OA的原始文件路径,用于保存时分析,是否进行了另存为操作 - - if (doc) { - var l_p = JSON.stringify(l_Param); - - //将OA文档标志存入系统变量对象保存 - wps.PluginStorage.setItem(doc.FullName, l_p); - } -} - -/** - * 作用:设置Ribbon工具条的按钮显示状态 - * @param {*} paramsGroups - */ -function pDoResetRibbonGroups(paramsGroups) { - -} - -/** - * 按照定时器的时间,自动执行所有文档的自动保存事件 - */ -function OnDocSaveByAutoTimer() { - var l_Doc; - - var l_Count = 0 - var l_docCounts = wps.EtApplication().Workbooks.Count; - for (l_Count = 0; l_Count < l_docCounts; l_Count++) { - l_Doc = wps.EtApplication().Workbooks.Item(l_Count); - if (l_Doc) { - if (pCheckIfOADoc(l_Doc) == true) { // 是否为OA文件 - if (pISOADocReadOnly(l_Doc) == false) { // 是否为只读文档 - //执行自动上传到OA服务器端的操作 - pAutoUploadToServer(l_Doc); - //保存该文档对应的访问过程记录信息 - } - } - } - } -} - -/** - * 实现一个定时器 - */ -function OpenTimerRun(funcCallBack) { - var l_mCount = 0; //设置一个计时器,按每分钟执行一次; 10分钟后重复执行 - var l_timeID = 0; //用于保存计时器ID值 - - // 对间隔时间做处理 - var l_AutoSaveToServerTime = wps.PluginStorage.getItem("AutoSaveToServerTime"); - if (l_AutoSaveToServerTime == 0) { // 设置为0则不启动定时器 - l_timeID = wps.PluginStorage.getItem("TempTimerID"); - clearInterval(l_timeID); - return; - } else if (l_AutoSaveToServerTime < 3) { - l_AutoSaveToServerTime = 3; - } - - l_timeID = setInterval(function () { - l_mCount = l_mCount + 1; - if (l_mCount > l_AutoSaveToServerTime) { //l_AutoSaveToServerTime 值由系统配置时设定,见pInitParameters()函数 - l_mCount = 0; - funcCallBack(); //每隔l_AutoSaveToServerTime 分钟(例如10分钟)执行一次回调函数 - } - }, 60000); //60000 每隔1分钟,执行一次操作(1000*60) - - - wps.PluginStorage.setItem("TempTimerID", l_timeID); //保存计时器ID值 -} \ No newline at end of file diff --git a/oaassist/EtOAAssist/js/common/func_oastarter.js b/oaassist/EtOAAssist/js/common/func_oastarter.js deleted file mode 100644 index 4ee7117..0000000 --- a/oaassist/EtOAAssist/js/common/func_oastarter.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * web页面调用WPS加载项的方法入口 - * * info参数结构 - * info:[ - * { - * '方法名':'方法参数',需要执行的方法 - * }, - * ... - * ] - * @param {*} info - */ -function dispatcher(info) { - var funcs = info.funcs; - //NotifyToWeb(); - //alert(JSON.stringify(funcs)); - //执行web页面传递的方法 - for (var index = 0; index < funcs.length; index++) { - var func = funcs[index]; - for (var key in func) { - func[key].isOA=true - if (key === "OpenDoc") { // OpenDoc 属于普通的打开文档的操作方式,文档落地操作 - OpenDoc(func[key]); //进入打开文档处理函数 - } else if (key === "OnlineEditDoc") { //在线方式打开文档,属于文档不落地的方式打开 - OnlineEditDoc(func[key]); - } else if (key === "NewDoc") { - OpenDoc(func[key]); - } - } - } - return {message:"ok", app:wps.Application.Name} -} - -/** - * - * @param {*} params OA端传入的参数 - */ -function OnlineEditDoc(OaParams) { - //如果 - if (OaParams.fileName == "") { - NewFile(OaParams); - } else { - //OA传来下载文件的URL地址,调用openFile 方法打开 - OpenOnLineFile(OaParams); - } -} - -///打开来自OA端传递来的文档 -function OpenDoc(OaParams) { - //如果 - if (OaParams.fileName == "") { - NewFile(OaParams); - } else { - //OA传来下载文件的URL地址,调用openFile 方法打开 - OpenFile(OaParams); - } -} \ No newline at end of file diff --git a/oaassist/EtOAAssist/js/common/func_tabcontrol.js b/oaassist/EtOAAssist/js/common/func_tabcontrol.js deleted file mode 100644 index e0fde6d..0000000 --- a/oaassist/EtOAAssist/js/common/func_tabcontrol.js +++ /dev/null @@ -1,441 +0,0 @@ -var EnumOAFlag = { - DocFromOA: 1, - DocFromNoOA: 0 -} - -//记录是否用户点击OA文件的保存按钮 -var EnumDocSaveFlag = { - OADocSave: 1, - NoneOADocSave: 0 -} - -//标识文档的落地模式 本地文档落地 0 ,不落地 1 -var EnumDocLandMode = { - DLM_LocalDoc: 0, - DLM_OnlineDoc: 1 -} - -//加载时会执行的方法 -function OnWPSWorkTabLoad(ribbonUI) { - wps.ribbonUI = ribbonUI; - - OnJSWorkInit(); //初始化文档事件(全局参数,挂载监听事件) - activeTab(); // 激活OA助手菜单 - OpenTimerRun(OnDocSaveByAutoTimer); //启动定时备份过程 - return true; -} - -//文档各类初始化工作(WPS Js环境) -function OnJSWorkInit() { - pInitParameters(); //OA助手环境的所有配置控制的初始化过程 - AddWorkbookEvent(); //挂接文档事件处理函数 -} - - -//初始化全局参数 -function pInitParameters() { - wps.PluginStorage.setItem("OADocUserSave", EnumDocSaveFlag.NoneOADocSave); //初始化,没有用户点击保存按钮 - - var l_wpsUserName = wps.EtApplication().UserName; - wps.PluginStorage.setItem("WPSInitUserName", l_wpsUserName); //在OA助手加载前,先保存用户原有的WPS应用用户名称 - - wps.PluginStorage.setItem("OADocCanSaveAs", false); //默认OA文档不能另存为本地 - wps.PluginStorage.setItem("AllowOADocReOpen", false); //设置是否允许来自OA的文件再次被打开 - wps.PluginStorage.setItem("ShowOATabDocActive", false); //设置新打开文档是否默认显示OA助手菜单Tab //默认为false - - wps.PluginStorage.setItem("DefaultUploadFieldName", "file"); //针对UploadFile方法设置上载字段名称 - - wps.PluginStorage.setItem("AutoSaveToServerTime", "10"); //自动保存回OA服务端的时间间隔。如果设置0,则关闭,最小设置3分钟 - wps.PluginStorage.setItem("TempTimerID", "0"); //临时值,用于保存计时器ID的临时值 - - // 以下是一些临时状态参数,用于打开文档等的状态判断 - wps.PluginStorage.setItem("IsInCurrOADocOpen", false); //用于执行来自OA端的新建或打开文档时的状态 - wps.PluginStorage.setItem("IsInCurrOADocSaveAs", false); //用于执行来自OA端的文档另存为本地的状态 -} - -//挂载WPS的表格事件 -function AddWorkbookEvent() { - wps.ApiEvent.AddApiEventListener("WindowActivate", OnWindowActivate); - wps.ApiEvent.AddApiEventListener("WorkbookBeforeClose", OnWorkbookBeforeClose); - wps.ApiEvent.AddApiEventListener("WorkbookBeforeSave", OnWorkbookBeforeSave); - wps.ApiEvent.AddApiEventListener("WorkbookOpen", OnWorkbookOpen); - wps.ApiEvent.AddApiEventListener("NewWorkbook", OnWorkbookNew); - console.log("AddWorkbookEvent"); -} - -/** - * 根据传入Document对象,获取OA传入的参数的某个Key值的Value - * @param {*} Doc - * @param {*} Key - * 返回值:返回指定 Key的 Value - */ -function GetDocParamsValue(Doc, Key) { - if (!Doc) { - return ""; - } - - var l_Params = wps.PluginStorage.getItem(Doc.FullName); - if (!l_Params) { - return ""; - } - - var l_objParams = JSON.parse(l_Params); - if (typeof (l_objParams) == "undefined") { - return ""; - } - - var l_rtnValue = l_objParams[Key]; - if (typeof (l_rtnValue) == "undefined" || l_rtnValue == null) { - return ""; - } - return l_rtnValue; -} - -/** - * 作用:根据OA传入参数,设置是否显示Ribbob按钮组 - * 参数:CtrlID 是OnGetVisible 传入的Ribbob控件的ID值 - */ -function pShowRibbonGroupByOADocParam(CtrlID) { - var l_Doc = wps.EtApplication().ActiveWorkbook; - if (!l_Doc) { - return false; //如果未装入文档,则设置OA助手按钮组不可见 - } - - //获取OA传入的按钮组参数组 - var l_grpButtonParams = GetDocParamsValue(l_Doc, "buttonGroups"); //disableBtns - l_grpButtonParams = l_grpButtonParams + "," + GetDocParamsValue(l_Doc, "disableBtns"); - // 要求OA传入控制自定义按钮显示的参数为字符串 中间用 , 分隔开 - if (typeof (l_grpButtonParams) == "string") { - var l_arrayGroup = new Array(); - l_arrayGroup = l_grpButtonParams.split(","); - //console.log(l_grpButtonParams); - - // 判断当前按钮是否存在于数组 - if (l_arrayGroup.indexOf(CtrlID) >= 0) { - return false; - } - } - // 添加OA菜单判断 - if (CtrlID == "WPSWorkExtTab") { - var l_value = wps.PluginStorage.getItem("ShowOATabDocActive"); - wps.PluginStorage.setItem("ShowOATabDocActive", false); //初始化临时状态变量 - console.log("菜单:" + l_value); - return l_value; - } - - //disableBtns - - return true; -} - -/** - * 调用文件上传到OA服务端时, - * @param {*} resp - * wdDoNotSaveChanges 0 *不保存待定的更改。 - * wdPromptToSaveChanges -2 *提示用户保存待定更改。 - * wdSaveChanges -1 *自动保存待定更改,而不提示用户。 - */ -function OnUploadToServerSuccess(resp) { - var l_doc = wps.EtApplication().ActiveWorkbook; - if (wps.confirm("文件上传成功!继续编辑请确认,取消关闭文档。") == false) { - if (l_doc) { - console.log("OnUploadToServerSuccess: before Close"); - l_doc.Close(-1); //保存文档后关闭 - console.log("OnUploadToServerSuccess: after Close"); - } - } - - var l_NofityURL = GetDocParamsValue(l_doc, "notifyUrl"); - if (l_NofityURL != "") { - l_NofityURL = l_NofityURL.replace("{?}", "2"); //约定:参数为2则文档被成功上传 - NotifyToServer(l_NofityURL); - } -} - -function OnUploadToServerFail(resp) { - alert("文件上传失败!"); -} - -//判断当前文档是否是OA文档 -function pCheckIfOADoc() { - var doc = wps.EtApplication().ActiveWorkbook; - if (!doc) - return false; - return CheckIfDocIsOADoc(doc); -} - -//根据传入的doc对象,判断当前文档是否是OA文档 -function CheckIfDocIsOADoc(doc) { - if (!doc) { - return false; - } - var l_isOA = GetDocParamsValue(doc, "isOA"); - if (l_isOA == "") { - return false - }; - return l_isOA == EnumOAFlag.DocFromOA ? true : false; -} - -//返回是否可以点击OA保存按钮的状态 -function OnSetSaveToOAEnable() { - return pCheckIfOADoc(); -} - -/** - * 作用:判断是否是不落地文档 - * 参数:doc 文档对象 - * 返回值: 布尔值 - */ -function pIsOnlineOADoc(doc) { - var l_LandMode = GetDocParamsValue(doc, "OADocLandMode"); //获取文档落地模式 - if (l_LandMode == "") { //用户本地打开的文档 - return false; - } - return l_LandMode == EnumDocLandMode.DLM_OnlineDoc; -} - -//保存到OA后台服务器 -function OnBtnSaveToServer() { - // console.log('SaveToServer'); - var l_doc = wps.EtApplication().ActiveWorkbook; - if (!l_doc) { - alert("空文档不能保存!"); - return; - } - - //非OA文档,不能上传到OA - if (pCheckIfOADoc() == false) { - alert("非系统打开的文档,不能直接上传到系统!"); - return; - } - - //如果是OA打开的文档,并且设置了保护的文档,则不能再上传到OA服务器 - if (pISOADocReadOnly(l_doc)) { - wps.alert("系统设置了保护的文档,不能再提交到系统后台。"); - return; - } - - /** - * 参数定义:OAAsist.UploadFile(name, path, url, field, "OnSuccess", "OnFail") - * 上传一个文件到远程服务器。 - * name:为上传后的文件名称; - * path:是文件绝对路径; - * url:为上传地址; - * field:为请求中name的值; - * 最后两个参数为回调函数名称; - */ - var l_uploadPath = GetDocParamsValue(l_doc, "uploadPath"); // 文件上载路径 - if (l_uploadPath == "") { - wps.alert("系统未传入文件上载路径,不能执行上传操作!"); - return; - } - - if (!wps.confirm("先保存文档,并开始上传到系统后台,请确认?")) { - return; - } - - var l_FieldName = GetDocParamsValue(l_doc, "uploadFieldName"); //上载到后台的字段名称 - if (l_FieldName == "") { - l_FieldName = wps.PluginStorage.getItem("DefaultUploadFieldName"); // 默认为‘file’ - } - - var l_UploadName = GetDocParamsValue(l_doc, "uploadFileName"); //设置OA传入的文件名称参数 - if (l_UploadName == "") { - l_UploadName = l_doc.Name; //默认文件名称就是当前文件编辑名称 - } - - var l_DocPath = l_doc.FullName; // 文件所在路径 - - if (pIsOnlineOADoc(l_doc) == false) { - //对于本地磁盘文件上传OA,先用Save方法保存后,再上传 - //设置用户保存按钮标志,避免出现禁止OA文件保存的干扰信息 - wps.PluginStorage.setItem("OADocUserSave", EnumDocSaveFlag.OADocSave); - l_doc.Save(); //执行一次保存方法 - //设置用户保存按钮标志 - wps.PluginStorage.setItem("OADocUserSave", EnumDocSaveFlag.NoneOADocSave); - //落地文档,调用UploadFile方法上传到OA后台 - try { - //调用OA助手的上传方法 - UploadFile(l_UploadName, l_DocPath, l_uploadPath, l_FieldName, OnUploadToServerSuccess, OnUploadToServerFail); - } catch (err) { - alert("上传文件失败!请检查系统上传参数及网络环境!"); - } - } else { - // 不落地的文档,调用 Document 对象的不落地上传方法 - wps.PluginStorage.setItem("OADocUserSave", EnumDocSaveFlag.OADocSave); - try { - //调用不落地上传方法 - l_doc.SaveAsUrl(l_UploadName, l_uploadPath, l_FieldName, "OnUploadToServerSuccess", "OnUploadToServerFail"); - } catch (err) { - alert("上传文件失败!请检查系统上传参数及网络环境,重新上传。"); - } - wps.PluginStorage.setItem("OADocUserSave", EnumDocSaveFlag.NoneOADocSave); - } - - //获取OA传入的 转其他格式上传属性 - var l_suffix = GetDocParamsValue(l_doc, "suffix"); - if (l_suffix == "") { - console.log("上传需转换的文件后缀名错误,无妨进行转换上传!"); - return; - } - - //判断是否同时上传PDF等格式到OA后台 - var l_uploadWithAppendPath = GetDocParamsValue(l_doc, "uploadWithAppendPath"); //标识是否同时上传OFD、PDF等格式的文件 - if (l_uploadWithAppendPath == "1") { - //调用转 pdf格式函数,强制关闭转换修订痕迹 - pDoChangeToOtherDocFormat(l_doc, l_suffix, false, false); // - } - return; -} - -/** - * 执行另存为本地文件操作 - */ -function OnBtnSaveAsLocalFile() { - - //初始化临时状态值 - wps.PluginStorage.setItem("OADocUserSave", false); - wps.PluginStorage.setItem("IsInCurrOADocSaveAs", false); - - //检测是否有文档正在处理 - var l_doc = wps.EtApplication().ActiveWorkbook; - if (!l_doc) { - alert("WPS当前没有可操作文档!"); - return; - } - - // 设置WPS文档对话框 2 FileDialogType:=msoFileDialogSaveAs - var l_ksoFileDialog = wps.EtApplication().FileDialog(2); - l_ksoFileDialog.InitialFileName = l_doc.Name; //文档名称 - - if (l_ksoFileDialog.Show() == -1) { // -1 代表确认按钮 - wps.PluginStorage.setItem("OADocUserSave", true); //设置保存为临时状态,在Save事件中避免OA禁止另存为对话框 - l_ksoFileDialog.Execute(); //会触发保存文档的监听函数 - - pSetNoneOADocFlag(l_doc); - wps.ribbonUI.Invalidate(); //刷新Ribbon的状态 - }; -} - -/** - * 获取对象中属性的值 - * @param {*} params - * @param {*} Key - */ -function GetParamsValue(Params, Key) { - if (typeof (Params) == "undefined") { - return ""; - } - - var l_rtnValue = Params[Key]; - return l_rtnValue; -} - - -function OnAction(control) { - var eleId; - if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 - eleId = control.Id; - } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 - eleId = arguments[1].Id; - } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 - eleId = arguments[1].Id; - } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 - eleId = arguments[2].Id; - } - switch (strId) { - case "btnSaveToServer": - OnBtnSaveToServer(); - break; - case "btnSaveAsFile": - OnBtnSaveAsLocalFile(); - break; - default: - ; - } - return true; -} - -function OnGetEnabled(control) { - var eleId; - if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 - eleId = control.Id; - } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 - eleId = arguments[1].Id; - } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 - eleId = arguments[1].Id; - } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 - eleId = arguments[2].Id; - } - switch (eleId) { - case "btnSaveToServer": //保存到OA服务器的相关按钮。判断,如果非OA文件,禁止点击 - return OnSetSaveToOAEnable(); - case "btnSaveAsFile": - let doc=wps.EtApplication().ActiveWorkbook; - let l_Params=wps.PluginStorage.getItem(doc.FullName); - let OADocLandMode=JSON.parse(l_Params).OADocLandMode - return !OADocLandMode - default: - ; - } - return true; -} - -function OnGetVisible(control) { - var eleId; - if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 - eleId = control.Id; - } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 - eleId = arguments[1].Id; - } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 - eleId = arguments[1].Id; - } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 - eleId = arguments[2].Id; - } - var l_value = false; - //按照 OA文档传递过来的属性进行判断 - l_value = pShowRibbonGroupByOADocParam(eleId); - return l_value; -} - -function GetImage(control) { - var eleId; - if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 - eleId = control.Id; - } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 - eleId = arguments[1].Id; - } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 - eleId = arguments[1].Id; - } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 - eleId = arguments[2].Id; - } - switch (eleId) { - case "btnSaveToServer": //保存到OA后台服务端 - return "./icon/w_Save.png"; - case "btnSaveAsFile": //另存为本地文件 - return "./icon/w_SaveAs.png"; - default: - ; - } - return "./icon/c_default.png"; -} - -function OnGetLabel(control) { - var eleId; - if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 - eleId = control.Id; - } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 - eleId = arguments[1].Id; - } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 - eleId = arguments[1].Id; - } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 - eleId = arguments[2].Id; - } - switch (eleId) { - case "btnSaveAsFile": - return "另存为本地"; - default: - ; - } - return ""; -} \ No newline at end of file diff --git a/oaassist/EtOAAssist/js/main.js b/oaassist/EtOAAssist/js/main.js deleted file mode 100644 index 81578c3..0000000 --- a/oaassist/EtOAAssist/js/main.js +++ /dev/null @@ -1,9 +0,0 @@ -if (typeof (window.wps) == "undefined") { - window.wps = window; -} -var time=new Date().getTime() //添加时间戳,防止js文件使用浏览器缓存 -document.write(""); -document.write(""); -document.write(""); -document.write(""); -document.write(""); \ No newline at end of file diff --git a/oaassist/EtOAAssist/package.json b/oaassist/EtOAAssist/package.json deleted file mode 100644 index b945069..0000000 --- a/oaassist/EtOAAssist/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "EtOAAssist", - "addonType": "et", - "version": "1.0.0", - "description": "这个工程为WPS表格项目一个简单的OA场景集成的WPS加载项——OA助手,旨在帮助大家能够快速理解并熟悉WPS加载项机制以及和浏览器调用交互的流程。", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC" -} \ No newline at end of file diff --git a/oaassist/EtOAAssist/ribbon.xml b/oaassist/EtOAAssist/ribbon.xml deleted file mode 100644 index 2d8a051..0000000 --- a/oaassist/EtOAAssist/ribbon.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - -
- -
- - - - - - - \ No newline at end of file diff --git a/oaassist/WpsOAAssist/index.html b/oaassist/WpsOAAssist/index.html deleted file mode 100644 index 887c288..0000000 --- a/oaassist/WpsOAAssist/index.html +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/oaassist/WpsOAAssist/js/common/common.js b/oaassist/WpsOAAssist/js/common/common.js deleted file mode 100644 index 3c02027..0000000 --- a/oaassist/WpsOAAssist/js/common/common.js +++ /dev/null @@ -1,535 +0,0 @@ -// -------------------------- 通用常量 --------------------------- - -//OA门户网站用接口,配置默认服务器接口 -var OA_DOOR = { - templateDataUrl: undefined, //正文模板列表接口 - templateBaseURL: undefined, //指定正文模板基础接口 - redHeadsPath: undefined, //默认红头模板列表获取路径 - getRedHeadPath: undefined, //默认获取红头文件路径 - bookmarkPath: undefined, //书签列表接口 - redHeadsPath: undefined, //默认红头模板列表获取路径 -} - -// -------------------------- 通用方法 --------------------------- -//去除字符串左边空格 -String.prototype.ltrim = function () { - return this.replace(/(^\s*)/g, ""); -} - -//去除字符串右边空格 -String.prototype.rtrim = function () { - return this.replace(/(\s*$)/g, ""); -} - -//扩展js string endwith,startwith方法 -String.prototype.endWith = function (str) { - if (str == null || str == "" || this.length == 0 || str.length > this.length) - return false; - if (this.substring(this.length - str.length) == str) - return true; - else - return false; -} - -String.prototype.startWith = function (str) { - if (str == null || str == "" || this.length == 0 || str.length > this.length) - return false; - if (this.substr(0, str.length) == str) - return true; - else - return false; -} - -//UTF-16转UTF-8 -function utf16ToUtf8(s) { - if (!s) { - return; - } - var i, code, ret = [], - len = s.length; - for (i = 0; i < len; i++) { - code = s.charCodeAt(i); - if (code > 0x0 && code <= 0x7f) { - //单字节 - //UTF-16 0000 - 007F - //UTF-8 0xxxxxxx - ret.push(s.charAt(i)); - } else if (code >= 0x80 && code <= 0x7ff) { - //双字节 - //UTF-16 0080 - 07FF - //UTF-8 110xxxxx 10xxxxxx - ret.push( - //110xxxxx - String.fromCharCode(0xc0 | ((code >> 6) & 0x1f)), - //10xxxxxx - String.fromCharCode(0x80 | (code & 0x3f)) - ); - } else if (code >= 0x800 && code <= 0xffff) { - //三字节 - //UTF-16 0800 - FFFF - //UTF-8 1110xxxx 10xxxxxx 10xxxxxx - ret.push( - //1110xxxx - String.fromCharCode(0xe0 | ((code >> 12) & 0xf)), - //10xxxxxx - String.fromCharCode(0x80 | ((code >> 6) & 0x3f)), - //10xxxxxx - String.fromCharCode(0x80 | (code & 0x3f)) - ); - } - } - - return ret.join(''); - -} -var Base64 = { - _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", - encode: function(e) { - var t = ""; - var n, r, i, s, o, u, a; - var f = 0; - e = Base64._utf8_encode(e); - while (f < e.length) { - n = e.charCodeAt(f++); - r = e.charCodeAt(f++); - i = e.charCodeAt(f++); - s = n >> 2; - o = (n & 3) << 4 | r >> 4; - u = (r & 15) << 2 | i >> 6; - a = i & 63; - if (isNaN(r)) { - u = a = 64 - } else if (isNaN(i)) { - a = 64 - } - t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a) - } - return t - }, - decode: function(e) { - var t = ""; - var n, r, i; - var s, o, u, a; - var f = 0; - e = e.replace(/[^A-Za-z0-9+/=]/g, ""); - while (f < e.length) { - s = this._keyStr.indexOf(e.charAt(f++)); - o = this._keyStr.indexOf(e.charAt(f++)); - u = this._keyStr.indexOf(e.charAt(f++)); - a = this._keyStr.indexOf(e.charAt(f++)); - n = s << 2 | o >> 4; - r = (o & 15) << 4 | u >> 2; - i = (u & 3) << 6 | a; - t = t + String.fromCharCode(n); - if (u != 64) { - t = t + String.fromCharCode(r) - } - if (a != 64) { - t = t + String.fromCharCode(i) - } - } - t = Base64._utf8_decode(t); - return t - }, - _utf8_encode: function(e) { - e = e.replace(/rn/g, "n"); - var t = ""; - for (var n = 0; n < e.length; n++) { - var r = e.charCodeAt(n); - if (r < 128) { - t += String.fromCharCode(r) - } else if (r > 127 && r < 2048) { - t += String.fromCharCode(r >> 6 | 192); - t += String.fromCharCode(r & 63 | 128) - } else { - t += String.fromCharCode(r >> 12 | 224); - t += String.fromCharCode(r >> 6 & 63 | 128); - t += String.fromCharCode(r & 63 | 128) - } - } - return t - }, - _utf8_decode: function(e) { - var t = ""; - var n = 0; - var r = c1 = c2 = 0; - while (n < e.length) { - r = e.charCodeAt(n); - if (r < 128) { - t += String.fromCharCode(r); - n++ - } else if (r > 191 && r < 224) { - c2 = e.charCodeAt(n + 1); - t += String.fromCharCode((r & 31) << 6 | c2 & 63); - n += 2 - } else { - c2 = e.charCodeAt(n + 1); - c3 = e.charCodeAt(n + 2); - t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63); - n += 3 - } - } - return t - } -} -//UTF-8转UTF-16 -function utf8ToUtf16(s) { - if (!s) { - return; - } - - var i, codes, bytes, ret = [], - len = s.length; - for (i = 0; i < len; i++) { - codes = []; - codes.push(s.charCodeAt(i)); - if (((codes[0] >> 7) & 0xff) == 0x0) { - //单字节 0xxxxxxx - ret.push(s.charAt(i)); - } else if (((codes[0] >> 5) & 0xff) == 0x6) { - //双字节 110xxxxx 10xxxxxx - codes.push(s.charCodeAt(++i)); - bytes = []; - bytes.push(codes[0] & 0x1f); - bytes.push(codes[1] & 0x3f); - ret.push(String.fromCharCode((bytes[0] << 6) | bytes[1])); - } else if (((codes[0] >> 4) & 0xff) == 0xe) { - //三字节 1110xxxx 10xxxxxx 10xxxxxx - codes.push(s.charCodeAt(++i)); - codes.push(s.charCodeAt(++i)); - bytes = []; - bytes.push((codes[0] << 4) | ((codes[1] >> 2) & 0xf)); - bytes.push(((codes[1] & 0x3) << 6) | (codes[2] & 0x3f)); - ret.push(String.fromCharCode((bytes[0] << 8) | bytes[1])); - } - } - return ret.join(''); - -} - -function currentTime() { - var now = new Date(); - - var year = now.getFullYear(); //年 - var month = now.getMonth() + 1; //月 - var day = now.getDate(); //日 - - var hh = now.getHours(); //时 - var mm = now.getMinutes(); //分 - var ss = now.getSeconds(); - var clock = year + ""; - - if (month < 10) - clock += "0"; - - clock += month + ""; - - if (day < 10) - clock += "0"; - - clock += day + ""; - - if (hh < 10) - clock += "0"; - - clock += hh + ""; - if (mm < 10) clock += '0'; - clock += mm; - if (ss < 10) clock += '0'; - clock += ss; - return (clock); -} - -/** - * 获取文件路径 - * @param {*} html 文件全称 - */ -function getHtmlURL(html) { - //弹出辅助窗格框 - var GetUrlPath = ()=> { - var e = document.location.toString(); - return -1 != (e = decodeURI(e)).indexOf("/") && (e = e.substring(0, e.lastIndexOf("/"))), e - } - - var url = GetUrlPath(); - - if (url.length != 0) { - url = url.concat("/" + html); - } else { - url = url.concat("./" + html); - } - return url; -} - -/** - * wps内弹出web页面 - * @param {*} html 文件名 - * @param {*} title 窗口标题 - * @param {*} hight 窗口高 - * @param {*} width 窗口宽 - */ -function OnShowDialog(html, title, height, width, bModal) { - var l_ActiveDoc = wps.WpsApplication().ActiveDocument; - if (!l_ActiveDoc) { - alert("WPS当前没有可操作文档!") - return; - } - if (typeof bModal == "undefined" || bModal == null) { - bModal = true; - } - width *= window.devicePixelRatio; - height *= window.devicePixelRatio; - var url = getHtmlURL(html); - wps.ShowDialog(url, title, height, width, bModal); -} - -/** - * 解析返回response的参数 - * @param {*} resp - * @return {*} body - */ -function handleResultBody(resp) { - var result = ""; - if (resp.Body) { - // 解析返回response的参数 - } - return result; -} - - -/** - * 判断WPS中的文件个数是否为0,若为0则关闭WPS函数 - * @param {*} name - */ -function closeWpsIfNoDocument() { - var wpsApp = wps.WpsApplication(); - var docs = wpsApp.Documents; - if (!docs || docs.Count == 0) { - wps.ApiEvent.Cancel = true; - //根据业务可以选择是否退出进程 wpsApp.Quit(); - } -} - -function activeTab() { - //启动WPS程序后,默认显示的工具栏选项卡为ribbon.xml中某一tab - if (wps.ribbonUI) - wps.ribbonUI.ActivateTab('WPSWorkExtTab'); -} - -function showOATab() { - wps.PluginStorage.setItem("ShowOATabDocActive", pCheckIfOADoc()); //根据文件是否为OA文件来显示OA菜单 - wps.ribbonUI.Invalidate(); // 刷新Ribbon自定义按钮的状态 -} - -function getDemoTemplatePath() { - var url = document.location.toString(); - url = decodeURI(url); - if (url.indexOf("/") != -1) { - url = url.substring(0, url.lastIndexOf("/")); - } - if (url.length !== 0) - url = url.concat("/template/红头文件.docx"); - - if (url.startsWith("file:///")) - url = url.substr("file:///".length); - return url; -} - -function getDemoSealPath() { - var url = document.location.toString(); - url = decodeURI(url); - if (url.indexOf("/") != -1) { - url = url.substring(0, url.lastIndexOf("/")); - } - if (url.length !== 0) - url = url.concat("/template/OA模板:公章.png"); - - if (url.startsWith("file:///")) - url = url.substr("file:///".length); - return url; -} - -function pGetParamName(data, attr) { - var start = data.indexOf(attr); - data = data.substring(start + attr.length); - return data; -} -/** - * 从requst中获取文件名(确保请求中有filename这个参数) - * @param {*} request - * @param {*} url - */ - function pGetFileName(request, url) { - var disposition = request.getResponseHeader("Content-Disposition"); - var filename = ""; - if (disposition) { - var matchs = pGetParamName(disposition, "filename="); - if (matchs) { - filename = decodeURIComponent(matchs); - } else { - filename = "petro" + Date.getTime(); - } - } else { - filename = url.substring(url.lastIndexOf("/") + 1); - filename=filename.split("?")[0] - } - return filename; -} - -function StringToUint8Array(string) { - var binLen, buffer, chars, i, _i; - binLen = string.length; - buffer = new ArrayBuffer(binLen); - chars = new Uint8Array(buffer); - for (var i = 0; i < binLen; ++i) { - chars[i] = String.prototype.charCodeAt.call(string, i); - } - return buffer; -} -/** - * WPS下载文件到本地打开(业务系统可根据实际情况进行修改) - * @param {*} url 文件流的下载路径 - * @param {*} callback 下载后的回调 - */ -function DownloadFile(url, callback) { - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function () { - if (this.readyState == 4 && this.status == 200) { - //需要业务系统的服务端在传递文件流时,确保请求中的参数有filename - var fileName = pGetFileName(xhr, url) - //落地打开模式下,WPS会将文件下载到本地的临时目录,在关闭后会进行清理 - var path = wps.Env.GetTempPath() + "/" + fileName - var reader = new FileReader(); - reader.onload = function () { - wps.FileSystem.writeAsBinaryString(path, reader.result); - callback(path); - }; - reader.readAsBinaryString(xhr.response); - } - } - xhr.open('GET', url); - xhr.responseType = 'blob'; - xhr.send(); -} -/** - * WPS上传文件到服务端(业务系统可根据实际情况进行修改,为了兼容中文,服务端约定用UTF-8编码格式) - * @param {*} strFileName 上传到服务端的文件名称(包含文件后缀) - * @param {*} strPath 上传文件的文件路径(文件在操作系统的绝对路径) - * @param {*} uploadPath 上传文件的服务端地址 - * @param {*} strFieldName 业务调用方自定义的一些内容可通过此字段传递,默认赋值'file' - * @param {*} OnSuccess 上传成功后的回调 - * @param {*} OnFail 上传失败后的回调 - */ -function UploadFile(strFileName, strPath, uploadPath, strFieldName, OnSuccess, OnFail) { - var xhr = new XMLHttpRequest(); - xhr.open('POST', uploadPath); - - var fileData = wps.FileSystem.readAsBinaryString(strPath); - var data = new FakeFormData(); - if (strFieldName == "" || typeof strFieldName == "undefined"){//如果业务方没定义,默认设置为'file' - strFieldName = 'file'; - } - data.append(strFieldName, { - name: utf16ToUtf8(strFileName), //主要是考虑中文名的情况,服务端约定用utf-8来解码。 - type: "application/octet-stream", - getAsBinary: function () { - return fileData; - } - }); - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status == 200) - OnSuccess(xhr.response) - else - OnFail(xhr.response); - } - }; - xhr.setRequestHeader("Cache-Control", "no-cache"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - if (data.fake) { - xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + data.boundary); - var arr = StringToUint8Array(data.toString()); - xhr.send(arr); - } else { - xhr.send(data); - } -} - -/** - * 打开WPS后通知到业务系统,可根据需求扩展 - * @param {*} p_Url 业务方接受请求的地址 - */ -function NotifyToServer(p_Url) { - $.ajax({ - url: p_Url, // URL + '/wps/wpsCanOpen', - async: true, - method: "post", - dataType: 'json' - }); -} - -/** - * 更新编辑状态 - * @param {*} p_Url 要传入OA端,通知业务系统,当前文档所处的编辑状态的URL地址路径 - * @param {*} p_OpenUrl 当前文档从业务系统打开时的入口URL,这个URL包含业务系统开发者需要传入的ID等参数 - * @param {*} docId 文档id - * @param {*} state 0-正在编辑中 1-文件保存 2-文件关闭 状态可根据需要进行自定义扩展 - */ -function UpdateEditState(p_Url, p_OpenUrl, docId, state) { - var formData = { - "openUrl": p_OpenUrl, - "docId": docId, - "state": state - }; - $.ajax({ - url: p_Url, //URL + '/document/stateMonitor', - async: false, - data: formData, - method: "post", - dataType: 'json', - success: function (response) { - if (response == "success") { - console.log(response); - } - }, - error: function (response) { - console.log(response); - } - }); -} - -/** - * 作用:判断文档关闭后,如果系统已经没有打开的文档了,则设置回初始用户名 - */ -function pSetWPSAppUserName() { - //文档全部关闭的情况下,把WPS初始启动的用户名设置回去 - if (wps.WpsApplication().Documents.Count == 1) { - var l_strUserName = wps.PluginStorage.getItem(constStrEnum.WPSInitUserName); - wps.WpsApplication().UserName = l_strUserName; - } -} - -/** - * 设置文档参数的属性值 - * @param {*} Doc - * @param {*} Key - * @param {*} Value - */ -function SetDocParamsValue(Doc, Key, Value) { - if (!Doc || !Key) { - return; - } - - var l_Params = wps.PluginStorage.getItem(Doc.DocID); - if (!l_Params) { - return; - } - - var l_objParams = JSON.parse(l_Params); - if (!(typeof(l_objParams) == "undefined")) { - l_objParams[Key] = Value; - } - - //把属性值整体再写回原来的文档ID中 - wps.PluginStorage.setItem(Doc.DocID, JSON.stringify(l_objParams)); -} diff --git a/oaassist/WpsOAAssist/js/common/enum.js b/oaassist/WpsOAAssist/js/common/enum.js deleted file mode 100644 index 77b5849..0000000 --- a/oaassist/WpsOAAssist/js/common/enum.js +++ /dev/null @@ -1,115 +0,0 @@ -/** - * WPS常用的API枚举值,具体参与API文档 - */ -var WPS_Enum = { - wdDoNotSaveChanges: 0, - wdFormatPDF: 17, - wdFormatOpenDocumentText: 23, - wdFieldFormTextInput: 70, - wdAlertsNone: 0, - wdDialogFilePageSetup: 178, - wdDialogFilePrint: 88, - wdRelativeHorizontalPositionPage: 1, - wdGoToPage: 1, - wdPropertyPages: 14, - wdRDIComments: 1, - wdDialogInsertDateTime: 165, - msoCTPDockPositionLeft: 0, - msoCTPDockPositionRight: 2, - /** - * 将形状嵌入到文字中。 - */ - wdWrapInline: 7, - /** - * 将形状放在文字前面。 请参阅 wdWrapFront。 - */ - wdWrapNone: 3, - /** - * 使文字环绕形状。 行在形状的另一侧延续。 - */ - wdWrapSquare: 0, - /** - * 使文字环绕形状。 - */ - wdWrapThrough: 2, - /** - * 使文字紧密地环绕形状。 - */ - wdWrapTight: 1, - /** - * 将文字放在形状的上方和下方。 - */ - wdWrapTopBottom: 4, - /** - * 将形状放在文字后面。 - */ - wdWrapBehind: 5, - /** - * 将形状放在文字前面。 - */ - wdWrapFront: 6 -} - -/** - * WPS加载项自定义的枚举值 - */ -var constStrEnum = { - AllowOADocReOpen: "AllowOADocReOpen", - AutoSaveToServerTime: "AutoSaveToServerTime", - bkInsertFile: "bkInsertFile", - buttonGroups: "buttonGroups", - CanSaveAs: "CanSaveAs", - copyUrl: "copyUrl", - DefaultUploadFieldName: "DefaultUploadFieldName", - disableBtns: "disableBtns", - insertFileUrl: "insertFileUrl", - IsInCurrOADocOpen: "IsInCurrOADocOpen", - IsInCurrOADocSaveAs: "IsInCurrOADocSaveAs", - isOA: "isOA", - notifyUrl: "notifyUrl", - OADocCanSaveAs: "OADocCanSaveAs", - OADocLandMode: "OADocLandMode", - OADocUserSave: "OADocUserSave", - openType: "openType", - picPath: "picPath", - picHeight: "picHeight", - picWidth: "picWidth", - redFileElement: "redFileElement", - revisionCtrl: "revisionCtrl", - ShowOATabDocActive: "ShowOATabDocActive", - SourcePath: "SourcePath", - /** - * 保存文档到业务系统服务端时,另存一份其他格式到服务端,其他格式支持:.pdf .ofd .uot .uof - */ - suffix: "suffix", - templateDataUrl: "templateDataUrl", - TempTimerID: "TempTimerID", - /** - * 文档上传到业务系统的保存地址:服务端接收文件流的地址 - */ - uploadPath: "uploadPath", - /** - * 文档上传到服务端后的名称 - */ - uploadFieldName: "uploadFieldName", - /** - * 文档上传时的名称,默认取当前活动文档的名称 - */ - uploadFileName: "uploadFileName", - uploadAppendPath: "uploadAppendPath", - /** - * 标志位: 1 在保存到业务系统时再保存一份suffix格式的文档, 需要和suffix参数配合使用 - */ - uploadWithAppendPath: "uploadWithAppendPath", - userName: "userName", - WPSInitUserName: "WPSInitUserName", - taskpaneid: "taskpaneid", - /** - * 是否弹出上传前确认和成功后的确认信息:true|弹出,false|不弹出 - */ - Save2OAShowConfirm: "Save2OAShowConfirm", - /** - * 修订状态标志位 - */ - RevisionEnableFlag: "RevisionEnableFlag" -} \ No newline at end of file diff --git a/oaassist/WpsOAAssist/js/common/func_docEvents.js b/oaassist/WpsOAAssist/js/common/func_docEvents.js deleted file mode 100644 index f63b9cb..0000000 --- a/oaassist/WpsOAAssist/js/common/func_docEvents.js +++ /dev/null @@ -1,232 +0,0 @@ -// 打印前监听事件 -function OnDocumentBeforePrint(doc) { - return; -} - -//切换窗口时触发的事件 -function OnWindowActivate() { - var l_doc = wps.WpsApplication().ActiveDocument; - SetCurrDocEnvProp(l_doc); // 设置当前文档对应的用户名 - showOATab(); // 根据文件是否为OA文件来显示OA菜单再进行刷新按钮 - setTimeout(activeTab, 2000); // 激活页面必须要页签显示出来,所以做1秒延迟 - return; -} - -/** - * 作用:判断OA文档是否被另存为了 - */ -function CheckIfOADocSaveAs(doc) { - if (!doc) { - return; - } - // 获取OA文档的原始保存路径 - var l_Path = GetDocParamsValue(doc, constStrEnum.SourcePath); - // 原路径和当前文件的路径对比 - return l_Path == doc.FullName; -} - - -// 当文件保存前触发的事件 -function OnDocumentBeforeSave(doc) { - //设置变量,判断是否当前用户按了自定义的OA文件保存按钮 - if(wps.WpsApplication().ActiveDocument&&doc.DocID==wps.WpsApplication().ActiveDocument.DocID){ - var l_IsOADocButtonSave = false; - l_IsOADocButtonSave = wps.PluginStorage.getItem(constStrEnum.OADocUserSave); - - //根据传入参数判断当前文档是否能另存为,默认不能另存为 - if (pCheckCurrOADocCanSaveAs(doc) == false) { //先根据OA助手的默认设置判断是否允许OA文档另存为操作 - //0.如果配置文件:OA文档不允许另存为,则再判断 - //1.先判断是否是在线文档且是通过WPS自身按钮或快捷键保存,则取消弹出另存到本地的弹出框 - if (pIsOnlineOADoc(doc) == true && l_IsOADocButtonSave == false) { - alert("来自OA的不落地文档,禁止另存为本地文档!"); - //如果是OA文档,则禁止另存为 - wps.ApiEvent.Cancel = true; - } - //2.如果是落地打开的OA文档并且通过WPS自身按钮或者快捷键保存,则执行保存到本地临时目录,取消弹出对话框 - if (pIsOnlineOADoc(doc) == false && l_IsOADocButtonSave == false){ - //用户手动另存为操作时,在这里被屏蔽掉 - doc.Save(); - //如果是OA文档,则禁止另存为 - wps.ApiEvent.Cancel = true; - } - } - //保存文档后,也要刷新一下Ribbon按钮的状态 - showOATab(); - }else{ - wps.ApiEvent.Cancel=true; - } - return; -} - - -//文档保存前关闭事件 -/** - * 作用: - * @param {*} doc - */ -function OnDocumentBeforeClose(doc) { - console.log('OnDocumentBeforeClose'); - var l_fullName = doc.FullName; - var l_bIsOADoc = false; - l_bIsOADoc = CheckIfDocIsOADoc(doc); //判断是否OA文档要关闭 - if (l_bIsOADoc == false) { // 非OA文档不做处理 - return; - } - //判断是否只读的文档,或受保护的文档,对于只读的文档,不给予保存提示 - if (pISOADocReadOnly(doc) == false) { - if (doc.Saved == false) { //如果OA文档关闭前,有未保存的数据 - if (wps.confirm("系统文件有改动,是否提交后关闭?" + "\n" + "确认后请按上传按钮执行上传操作。取消则继续关闭文档。")) { - wps.ApiEvent.Cancel = true; - return; - } - } - } - // 有未保存的数据,确认无需保存直接关闭 - doc.Close(wps.Enum&&wps.Enum.wdDoNotSaveChanges||0); // 不保存待定的更改。枚举值兼容性写法 - closeWpsIfNoDocument(); // 判断WPS中的文件个数是否为0,若为0则关闭WPS函数 - wps.FileSystem.Remove(l_fullName); -} - - -//文档保存后关闭事件 -function OnDocumentAfterClose(doc) { - console.log("OnDocumentAfterClose"); - var l_NofityURL = GetDocParamsValue(doc, constStrEnum.notifyUrl); - if (l_NofityURL) { - l_NofityURL = l_NofityURL.replace("{?}", "3"); //约定:参数为3则文档关闭 - console.log("" + l_NofityURL); - NotifyToServer(l_NofityURL); - } - - pRemoveDocParam(doc); // 关闭文档时,移除PluginStorage对象的参数 - pSetWPSAppUserName(); // 判断文档关闭后,如果系统已经没有打开的文档了,则设置回初始用户名 -} - -//文档打开事件 -function OnDocumentOpen(doc) { - //设置当前新增文档是否来自OA的文档 - // if (wps.PluginStorage.getItem(constStrEnum.IsInCurrOADocOpen) == false) { - // //如果是用户自己在WPS环境打开文档,则设置非OA文档标识 - // console.log(wps.PluginStorage.getItem(wps.WpsApplication().ActiveDocument.DocID)) - // pSetNoneOADocFlag(doc); - // console.log(wps.PluginStorage.getItem(wps.WpsApplication().ActiveDocument.DocID)) - // } - OnWindowActivate(); - ChangeOATabOnDocOpen(); //打开文档后,默认打开Tab页 - setTimeout(activeTab,2000); // 激活OA助手菜单 -} - -//新建文档事件 -function OnDocumentNew(doc) { - //设置当前新增文档是否来自OA的文档 - // if (wps.PluginStorage.getItem(constStrEnum.IsInCurrOADocOpen) == false) { - // //如果是用户自己在WPS环境打开文档,则设置非OA文档标识 - // pSetNoneOADocFlag(doc); - // } - ChangeOATabOnDocOpen(); // 打开OA助手Tab菜单页 - wps.ribbonUI.Invalidate(); // 刷新Ribbon按钮的状态 -} - -/** - * 作用:判断当前文档是否是只读文档 - * 返回值:布尔 - */ -function pISOADocReadOnly(doc) { - if (!doc) { - return false; - } - var l_openType = GetDocParamsValue(doc, constStrEnum.openType); // 获取OA传入的参数 openType - if (l_openType == "") { - return false; - } - try { - if (l_openType.protectType != -1) { // -1 为未保护 - return true; - } - } catch (err) { - return false; - } -} - - -/** - * 作用:根据当前活动文档的情况判断,当前文档适用的系统参数,例如:当前文档对应的用户名称等 - */ -function SetCurrDocEnvProp(doc) { - if (!doc) return; - var l_bIsOADoc = false; - l_bIsOADoc = pCheckIfOADoc(doc); - - //如果是OA文件,则按OA传来的用户名设置WPS OA助手WPS用户名设置按钮冲突 - if (l_bIsOADoc == true) { - var l_userName = GetDocParamsValue(doc, constStrEnum.userName); - if (l_userName != "") { - wps.WpsApplication().UserName = l_userName; - return; - } - } - //如果是非OA文件或者参数的值是空值,则按WPS安装默认用户名设置 - wps.WpsApplication().UserName = wps.PluginStorage.getItem(constStrEnum.WPSInitUserName); -} - - - -/* - 入口参数:doc - 功能说明:判断当前文档是否能另存为本地文件 - 返回值:布尔值true or false -*/ -function pCheckCurrOADocCanSaveAs(doc) { - //如果是非OA文档,则允许另存为 - if (CheckIfDocIsOADoc(doc) == false) return true; - - //对于来自OA系统的文档,则获取该文档对应的属性参数 - var l_CanSaveAs = GetDocParamsValue(doc, constStrEnum.CanSaveAs); - - //判断OA传入的参数 - if (typeof (l_CanSaveAs) == "boolean") { - return l_CanSaveAs; - } - return false; -} - -/** - * 作用:文档关闭后,删除对应的PluginStorage内的参数信息 - * 返回值:没有返回值 - * @param {*} doc - */ -function pRemoveDocParam(doc) { - if (!doc) return; - wps.PluginStorage.removeItem(doc.DocID); - return; -} - -/** - * 作用:判断当前文档是否从OA来的文档,如果非OA文档(就是本地新建或打开的文档,则设置EnumOAFlag 标识) - * 作用:设置非OA文档的标识状态 - * @param {*} doc - * 返回值:无 - */ -function pSetNoneOADocFlag(doc) { - if (!doc) return; - var l_param = wps.PluginStorage.getItem(doc.DocID); //定义JSON文档参数 - var l_objParams = new Object(); - if (l_param) { - l_objParams = JSON.parse(l_param); - } - l_objParams.isOA = EnumOAFlag.DocFromNoOA; // 新增非OA打开文档属性 - wps.PluginStorage.setItem(doc.DocID, JSON.stringify(l_objParams)); // 存入内存中 -} - -/** - * 作用:根据设置判断打开文件是否默认激活OA助手工具Tab菜单 - * 返回值:无 - */ -function ChangeOATabOnDocOpen() { - var l_ShowOATab = true; //默认打开 - l_ShowOATab = wps.PluginStorage.getItem(constStrEnum.ShowOATabDocActive); - if (l_ShowOATab == true) { - setTimeout(activeTab,500); - // wps.ribbonUI.ActivateTab("WPSWorkExtTab"); //新建文档时,自动切换到OA助手状态 - } -} \ No newline at end of file diff --git a/oaassist/WpsOAAssist/js/common/func_docProcess.js b/oaassist/WpsOAAssist/js/common/func_docProcess.js deleted file mode 100644 index 0e48574..0000000 --- a/oaassist/WpsOAAssist/js/common/func_docProcess.js +++ /dev/null @@ -1,904 +0,0 @@ -/** - * 从OA调用传来的指令,打开本地新建文件 - * @param {*} fileUrl 文件url路径 - */ -function NewFile(params) { - //获取WPS Application 对象 - var wpsApp = wps.WpsApplication(); - wps.PluginStorage.setItem(constStrEnum.IsInCurrOADocOpen, true); //设置OA打开文档的临时状态 - //判断一下isOfficialDocument是否通过公文写作打开 - var doc; - if (params.isOfficialDocument) { - wps.Application.GetApplicationEx().NewOfficialDocument(); //新增使用公文写作打开的公文 - doc = wpsApp.ActiveDocument; - } else { - doc = wpsApp.Documents.Add(); //新增OA端文档 - } - wps.PluginStorage.setItem(constStrEnum.IsInCurrOADocOpen, false); - - //检查系统临时文件目录是否能访问 - if (wps.Env && wps.Env.GetTempPath) { - if (params.newFileName) { - //按OA传入的文件名称保存 - doc.SaveAs2($FileName = wps.Env.GetTempPath() + "/" + params.newFileName, undefined, undefined, undefined, false); - } else { - //OA传入空文件名称,则保存成系统时间文件 - if (params.isOfficialDocument) { - doc.SaveAs2($FileName = wps.Env.GetTempPath() + "/OA_" + currentTime(), 0, undefined, undefined, false); - } else { - doc.SaveAs2($FileName = wps.Env.GetTempPath() + "/OA_" + currentTime(), undefined, undefined, undefined, false); - } - } - } else { - alert("文档保存临时目录出错!不能保存新建文档!请联系系统开发商。"); - } - - var l_NofityURL = GetParamsValue(params, constStrEnum.notifyUrl); - if (l_NofityURL) { - NotifyToServer(l_NofityURL.replace("{?}", "1")); - } - - //Office文件打开后,设置该文件属性:从服务端来的OA文件 - pSetOADocumentFlag(doc, params); - //设置当前文档为 本地磁盘落地模式 - DoSetOADocLandMode(doc, EnumDocLandMode.DLM_LocalDoc); - //强制执行一次Activate事件 - OnWindowActivate(); - wps.WpsApplication().WindowState=1; - wps.WpsApplication().Activate(); //把WPS对象置前 - - return doc; //返回新创建的Document对象 -} - -/** - * 打开服务器上的文件 - * @param {*} fileUrl 文件url路径 - */ -function OpenFile(params) { - var l_strFileUrl = params.fileName; //来自OA网页端的OA文件下载路径 - var doc; - var l_IsOnlineDoc = false; //默认打开的是不落地文档 - if (l_strFileUrl) { - //下载文档之前,判断是否已下载该文件 - if (pCheckIsExistOpenOADoc(l_strFileUrl) == true) { - //如果找到相同OA地址文档,则给予提示 - wps.WpsApplication().WindowState=1; - wps.WpsApplication().Activate(); //把WPS对象置前 - //根据OA助手对是否允许再次打开相同文件的判断处理 - var l_AllowOADocReOpen = false; - l_AllowOADocReOpen = wps.PluginStorage.getItem(constStrEnum.AllowOADocReOpen); - if (l_AllowOADocReOpen == false) { - alert("已打开相同的OA文件,请关闭之前的文件,再次打开。"); - wps.WpsApplication().Activate(); - return null; - } else { - //处理重复打开相同OA 文件的方法 - var nDocCount = wps.WpsApplication().Documents.Count; - pReOpenOADoc(l_strFileUrl); - //重复打开的文档采用不落地的方式打开 - // 不落地方式打开文档判断落地比较多,V1版本先暂时关闭 - l_IsOnlineDoc = true; - var nDocCount_New = wps.WpsApplication().Documents.Count; - if (nDocCount_New > nDocCount) { - doc = wps.WpsApplication().ActiveDocument; - } - } - } else { - //如果当前没有打开文档,则另存为本地文件,再打开 - if (l_strFileUrl.startWith("http")) { // 网络文档 - DownloadFile(l_strFileUrl, function(path) { - if (path == "") { - alert("从服务端下载路径:" + l_strFileUrl + "\n" + "获取文件下载失败!"); - return null; - } - - doc = pDoOpenOADocProcess(params, path); - pOpenFile(doc, params, l_IsOnlineDoc); - }); - return; - } else { //本地文档 - doc = pDoOpenOADocProcess(params, l_strFileUrl); - if (doc) - doc.SaveAs2($FileName = wps.Env.GetTempPath() + "/" + doc.Name, undefined, undefined, undefined, false); - } - } - } else { - //fileURL 如果为空,则按新建OA本地文件处理 - NewFile(params); - } - //如果打开pdf等其他非Office文档,则doc对象为空 - if (!doc) { - return null; - } - - pOpenFile(doc, params, l_IsOnlineDoc); -} - -/** - * 作用:文档打开后执行的动作集合 - * @param {*} doc 文档对象 - * @param {*} params 前端传递的参数集合 - * @param {*} isOnlineDoc 在线打开/落地打开 - */ -function pOpenFile(doc, params, isOnlineDoc) { - var l_IsOnlineDoc = isOnlineDoc - //Office文件打开后,设置该文件属性:从服务端来的OA文件 - pSetOADocumentFlag(doc, params) - //设置当前文档为 本地磁盘落地模式 - if (l_IsOnlineDoc == true) { - DoSetOADocLandMode(doc, EnumDocLandMode.DLM_OnlineDoc); - } else { - DoSetOADocLandMode(doc, EnumDocLandMode.DLM_LocalDoc); - } - - if (GetParamsValue(params, constStrEnum.templateDataUrl)) { - GetServerTemplateData(doc, params[constStrEnum.templateDataUrl]); - } - - if (GetParamsValue(params, constStrEnum.insertFileUrl)) { - InsertRedHeadDoc(doc); - } - - var l_NofityURL = GetParamsValue(params, constStrEnum.notifyUrl); - if (l_NofityURL) { - l_NofityURL = l_NofityURL.replace("{?}", "1"); //约定:参数为1则代码打开状态 - NotifyToServer(l_NofityURL); - } - //重新设置工具条按钮的显示状态 - pDoResetRibbonGroups(); - // 触发切换窗口事件 - OnWindowActivate(); - // 把WPS对象置前 - wps.WpsApplication().WindowState=1; - wps.WpsApplication().Activate(); - return doc; -} - - - -/** - * 套用模板插入文字/图片/文档 - * * params参数结构 - * params:{ - * 'docId': docId, //文档ID - * 'templateURL':'',获取模板接口 - * 'fileName':'',获取文档接口 - * 'uploadPath':'',文档保存上传接口 - * } - * 这个功能要求服务端传来的模板JSON数据字符串,支持三种类型定义: - * text 类型:直接插入对应的书签位置 - * link 类型: 把对应的URL的文件插入到指定的书签位置 - * pic 类型: 把对应的URL的图片文件插入到指定的书签位置 - * @param {*} params - */ -function GetServerTemplateData(template, pTemplateDataUrl) { - //获取文档内容 - $.ajax({ - url: pTemplateDataUrl, - async: false, - method: "get", - dataType: 'json', - success: function(res) { - var data = res; - let Bookmarks = template.Bookmarks; - data.forEach(function(it) { - - var bookmark = Bookmarks.Item(it.name); - let bookStart = bookmark.Range.Start; - let bookEnd = bookmark.Range.End; - let start = template.Range().End - //方案1,直接替换,手动添加书签 - // if (bookmark) { - // if (!it.type || it.type === "text") { - // bookmark.Range.Text = it.text; - // } else if (it.type === "link") { - // bookmark.Range.InsertFile(it.text); - // } else if (it.type === "pic") { - // bookmark.Range.InlineShapes.AddPicture(it.text); - // } - // } - // let end = template.Range().End - // let range=bookmark.Range; - // if (!Bookmarks.Exists(bookmark.Name)) - // Bookmarks.Add(bookmark.Name, range.SetRange(bookStart, bookEnd + (end - start))) - - //方案2,不完全替换 - if(bookmark){ - if (!it.type || it.type === "text") { - bookmark.Range.InsertBefore(it.text); - } else if (it.type === "link") { - bookmark.Range.InsertFile(it.text); - } else if (it.type === "pic") { - bookmark.Range.InlineShapes.AddPicture(it.text); - } - } - var selection=wps.WpsApplication().ActiveWindow.Selection; - if (bookmark.Range.Text) { - selection.Start = bookmark.Range.End - (bookEnd - bookStart); - selection.End = bookmark.Range.End; - selection.Cut(); - } else { - selection.Start = bookmark.Range.End; - selection.End = bookmark.Range.End+it.text.length; - ActiveDocument.Bookmarks.Add(bookmark.Name, selection.Range); - } - }) - } - }); -} - -/** - * 打开服务端的文档(不落地) - * @param {*} fileUrl 文件url路径 - */ -function OpenOnLineFile(OAParams) { - //OA参数如果为空的话退出 - if (!OAParams) return; - - //获取在线文档URL - var l_OAFileUrl = OAParams.fileName; - var l_doc; - if (l_OAFileUrl) { - //下载文档不落地(16版WPS的925后支持) - wps.WpsApplication().Documents.OpenFromUrl(l_OAFileUrl, "OnOpenOnLineDocSuccess", "OnOpenOnLineDocDownFail"); - l_doc = wps.WpsApplication().ActiveDocument; - } - //执行文档打开后的方法 - pOpenFile(l_doc, OAParams, true); - return l_doc; -} - - -/** - * 打开在线文档成功后触发事件 - * @param {*} resp - */ -function OnOpenOnLineDocSuccess(resp) { - -} - - -/** - * 打开在线不落地文档出现失败时,给予错误提示 - */ -function OnOpenOnLineDocDownFail(res) { - var err={} - try{ - res=JSON.parse(res) - err.Body=Base64.decode(res.Body) - err.Headers=Base64.decode(JSON.stringify(res.Headers)) - console.log(err) - }catch(err){ - - } - alert("打开在线不落地文档失败!请尝试重新打开。"); - return; -} - -/** - * 参数: - * doc : 当前OA文档的Document对象 - * DocLandMode : 落地模式设置 - */ -function DoSetOADocLandMode(doc, DocLandMode) { - if (!doc) return; - var l_Param = wps.PluginStorage.getItem(doc.DocID); - var l_objParam = JSON.parse(l_Param); - //增加属性,或设置 - l_objParam.OADocLandMode = DocLandMode; //设置OA文档的落地标志 - - var l_p = JSON.stringify(l_objParam); - //将OA文档落地模式标志存入系统变量对象保存 - - wps.PluginStorage.setItem(doc.DocID, l_p); - -} - - -/** - * 作用:设置Ribbon工具条的按钮显示状态 - * @param {*} paramsGroups - */ -function pDoResetRibbonGroups(paramsGroups) { - -} - -/** - * 作用:打开文档处理的各种过程,包含:打开带密码的文档,保护方式打开文档,修订方式打开文档等种种情况 - * params Object OA Web端传来的请求JSON字符串,具体参数说明看下面数据 - * TempLocalFile : 字符串 先把文档从OA系统下载并保存在Temp临时目录,这个参数指已经下载下来的本地文档地址 - * ----------------------以下是OA参数的一些具体规范名称 - * docId String 文档ID - * uploadPath String 保存文档接口 - * fileName String 获取服务器文档接口(不传即为新建空文档) - * suffix String ".pdf|.uot",可传多个,用“|”分割,保存时会按照所传的值转成对应的格式文档并上传 - * userName String 用于更改显示修改人的用户名 - * strBookmarkDataPath string 书签列表 (可不传,可以在OA助手config.js中配置) - * templatePath string 模板列表 (可不传,可以在OA助手config.js中配置) - * buttonGroups string 自定义按钮组 (可不传,不传显示所有按钮) - * revisionCtrl String 痕迹控制 ,不传正常打开 - * bOpenRevision String true(打开)false(关闭)修订 - * bShowRevision String true(显示)/false(关闭)痕迹 - * openType String 文档打开方式 ,不传正常打开 - * protectType String 文档保护类型,-1:不启用保护模式,0:只允许对现有内容进行修订,1:只允许添加批注,2:只允许修改窗体域,3:只读 - * password String密码 - */ -function pDoOpenOADocProcess(params, TempLocalFile) { - var l_ProtectType = -1; //默认文档保护类型 -1 为不启用保护 - var l_ProtectPassword = ""; //默认文档密码为空 - - var l_strDocPassword = ""; //打开文档密码参数 - var l_bOpenRevision = false; //初始化关闭修订模式 - var l_bShowRevision = false; //初始化不显示修订气泡样式 - - for (var key = "" in params) { - switch (key.toUpperCase()) // - { - case "userName".toUpperCase(): //修改当前文档用户名 - wps.WpsApplication().UserName = params[key]; - break; - case "openType".toUpperCase(): - l_ProtectType = params[key].protectType; //获取OA传来的文档保护类型 - l_ProtectPassword = params[key].password; //获取OA传来的保护模式下的文档密码 - break; - case "revisionCtrl".toUpperCase(): //限制修订状态 - l_bOpenRevision = params[key].bOpenRevision; - l_bShowRevision = params[key].bShowRevision; - break; - case "buttonGroups".toUpperCase(): //按钮组合 - break; - case "docPassword".toUpperCase(): //传入打开文件的密码 - l_strDocPassword = params[key].docPassword; - break; - } - - } - - var l_Doc; - // Open方法的参数说明如下 - //Function Open(FileName, [ConfirmConversions], [ReadOnly], [AddToRecentFiles], - // [PasswordDocument], [PasswordTemplate], [Revert], [WritePasswordDocument], - // [WritePasswordTemplate], [Format], [Encoding], [Visible], - // [OpenAndRepair], [DocumentDirection], [NoEncodingDialog], [XMLTransform]) As Document - l_Doc = wps.WpsApplication().Documents.Open(TempLocalFile, false, false, false, l_strDocPassword); - - //设置文档修订状态 - DoOADocOpenRevision(l_Doc, l_bOpenRevision, l_bShowRevision); - - //打开文档后,根据保护类型设置文档保护 - if (l_ProtectType > -1) // -1 :不设置文档保护 - SetOADocProtect(l_Doc, l_ProtectType, l_ProtectPassword); - return l_Doc; -} - - -/** - * protectType: '', 文档保护模式( -1:不启用保护模式, - * 0:只允许对现有内容进行修订, - * 1:只允许添加批注, - * 2:只允许修改窗体域, - * 3:只读) - * @param {*} protectType - * @param {*} doc - */ -function SetOADocProtect(doc, protectType, ProtectPassword) { - if (!doc) return; //校验文档是否存在 - if ([0, 1, 2, 3].indexOf(protectType) !== -1) { - // 保护文档如果之前有被保护,再次保护会出问题,需要先解除保护 - doc.Unprotect(); - // ** 方法参数 - // ** Protect(Type As WdProtectionType, [NoReset], [Password], [UseIRM], [EnforceStyleLock]) - doc.Protect(protectType, false, ProtectPassword, false); - } - return; -} - - - - -/** - * 打开/关闭修订 - * @param {*} doc :传入文档对象 - * @param {*} bOpenRevision : 布尔值,是否允许打开修订模式,true:打开/false:关闭 - * @param {*} bOpenRevision : 布尔值,是否显示修订痕迹状态 - * 返回值:无 - */ -function DoOADocOpenRevision(doc, bOpenRevision, bShowRevision) { - if (!doc) return; - - doc.TrackRevisions = bOpenRevision; //如果标记对指定文档的修改,则该属性值为True - var l_v = doc.ActiveWindow.View; - l_v.ShowRevisionsAndComments = bShowRevision; //如果为True,则 WPS 显示使用“修订”功能对文档所作的修订和批注 - l_v.RevisionsBalloonShowConnectingLines = bShowRevision; //如果为 True,则 WPS 显示从文本到修订和批注气球之间的连接线 - wps.WpsApplication().CommandBars.ExecuteMso("KsoEx_RevisionCommentModify_Disable"); //去掉修改痕迹信息框中的接受修订和拒绝修订勾叉,使其不可用 - - - if (bShowRevision) { - doc.ActiveWindow.ActivePane.View.RevisionsMode = 2; //2为不支持气泡显示。 - } - - //如果关闭修订,关闭显示痕迹并将按钮至灰 - wps.ribbonUI.InvalidateControl("btnOpenRevision"); - wps.ribbonUI.InvalidateControl("btnShowRevision"); - - return; -} - - - -/** - * 描述:如何处理再次打开相同的OA文件 - * 返回值:打开的Document对象 - */ -function pReOpenOADoc(OADocURL) { - if (wps.confirm("当前环境已打开该文件,是否重新再打开一份?")) { - //如果用户选择再次打开,则用在线方式打开 - wps.WpsApplication().Documents.OpenFromUrl(OADocURL, "", ""); - } -} - -/** - * 功能说明:判断是否已存在来自OA的已打开的文档 - * @param {字符串} FileURL - */ -function pCheckIsExistOpenOADoc(FileURL) { - var l_DocCount = wps.WpsApplication().Documents.Count; - if (l_DocCount <= 0) return false; - - //轮询检查当前已打开的WPS文档中,是否存在OA相同的文件 - if (l_DocCount >= 1) { - for (var l_index = 1; l_index <= l_DocCount; l_index++) { - var l_objDoc = wps.WpsApplication().Documents.Item(l_index); - - var l_strParam = wps.PluginStorage.getItem(l_objDoc.DocID); - if (l_strParam == null) - continue; - var l_objParam = JSON.parse(l_strParam) - if (l_objParam.fileName == FileURL) { - return true; - } - } - return false; - } -} - -//Office文件打开后,设置该文件属性:从服务端来的OA文件 -function pSetOADocumentFlag(doc, params) { - if (!doc) { - return; // - } - - var l_Param = params; - l_Param.isOA = EnumOAFlag.DocFromOA; //设置OA打开文档的标志 - - l_Param.SourcePath = doc.FullName; //保存OA的原始文件路径,用于保存时分析,是否进行了另存为操作 - //console.log(l_Param.SourcePath); - - if (doc) { - var l_p = JSON.stringify(l_Param); - //将OA文档标志存入系统变量对象保存 - wps.PluginStorage.setItem(doc.DocID, l_p); - } -} - -/** - * 作用: - * @param {*} suffix :文档后缀明:.pdf 或 .uot 或 .uof - * @param {*} doc - * @param {*} uploadPath - * @param {} FieldName : 上传到服务器端的字段名称,可由OA传入的参数设置 - * - * 返回值:是否执行了上传操作,布尔值 - */ -function handleFileAndUpload(suffix, doc, uploadPath, FieldName) { - var l_strChangeFileName = ""; // 转换格式后的文件名称 - var l_strPath = ""; // 转换格式后的文件路径 - var l_FieldName = FieldName; - - if (!doc) { - return false; - } - if (!l_FieldName) { - l_FieldName = "file"; //默认情况下,设置为 file 字段名称 - } - - var l_DocSourcePath = doc.FullName; //保留当前文档明,在SaveAs使用后再保存回原来的文件明 - - //Sub ExportAsFixedFormat(OutputFileName As String, ExportFormat As WdExportFormat, - // [OpenAfterExport As Boolean = False], - // [OptimizeFor As WdExportOptimizeFor = wdExportOptimizeForPrint], - // [Range As WdExportRange = wdExportAllDocument], [From As Long = 1], - // [To As Long = 1], [Item As WdExportItem = wdExportDocumentContent], - // [IncludeDocProps As Boolean = False], [KeepIRM As Boolean = True], - // [CreateBookmarks As WdExportCreateBookmarks = wdExportCreateNoBookmarks], - // [DocStructureTags As Boolean = True], [BitmapMissingFonts As Boolean = True], - // [UseISO19005_1 As Boolean = False], [FixedFormatExtClassPtr]) - - // Const wdExportFormatPDF = 17 (&H11) - // Const wdExportFormatXPS = 18 (&H12) - // - - //根据传入的 后缀文件名称进行不同的转换文档操作 - switch (suffix.toLocaleLowerCase()) { - case '.pdf': - l_strPath = pGetValidDocTempPath(doc) + ".pdf"; //获取有效输出路径 - wps.FileSystem.Remove(l_strPath); //先删除之前可能存在的临时文件 - doc.ExportAsFixedFormat(l_strPath, wps.Enum&&wps.Enum.wdFormatPDF||17, true); //文档另存为PDF格式 - l_strChangeFileName = doc.Name.split(".")[0] + ".pdf"; - UploadFile(l_strChangeFileName, l_strPath, uploadPath, l_FieldName, OnChangeSuffixUploadSuccess, OnChangeSuffixUploadFail); - break; - case '.uof': - l_strPath = pGetValidDocTempPath(doc) + suffix; - wps.FileSystem.Remove(l_strPath); //先删除之前可能存在的临时文件 - doc.ExportAsFixedFormat(l_strPath, wps.Enum&&wps.Enum.wdFormatOpenDocumentText||23, true); //转换文件格式 - doc.SaveAs2(l_strPath); - l_strChangeFileName = doc.Name.split(".")[0] + suffix; - UploadFile(l_strChangeFileName, l_strPath, uploadPath, l_FieldName, OnChangeSuffixUploadSuccess, OnChangeSuffixUploadFail); - doc.SaveAs2(l_DocSourcePath); //保存回原来的文档内容 - break; - case '.uot': - l_strPath = pGetValidDocTempPath(doc) + suffix; - wps.FileSystem.Remove(l_strPath); //先删除之前可能存在的临时文件 - doc.ExportAsFixedFormat(l_strPath, wps.Enum&&wps.Enum.wdFormatOpenDocumentText||23, true); - doc.SaveAs2(l_strPath); - l_strChangeFileName = doc.Name.split(".")[0] + suffix; - UploadFile(l_strChangeFileName, l_strPath, uploadPath, l_FieldName, OnChangeSuffixUploadSuccess, OnChangeSuffixUploadFail); - doc.SaveAs2(l_DocSourcePath); //保存回原来的文档内容 - break; - case '.ofd': - l_strPath = pGetValidDocTempPath(doc) + suffix; - wps.FileSystem.Remove(l_strPath); //先删除之前可能存在的临时文件 - doc.ExportAsFixedFormat(l_strPath, wps.Enum&&wps.Enum.wdFormatOpenDocumentText||23, true); - doc.SaveAs2(l_strPath,102); - l_strChangeFileName = doc.Name.split(".")[0] + suffix; - UploadFile(l_strChangeFileName, l_strPath, uploadPath, l_FieldName, OnChangeSuffixUploadSuccess, OnChangeSuffixUploadFail); - doc.SaveAs2(l_DocSourcePath); //保存回原来的文档内容 - break; - default: - l_strPath = pGetValidDocTempPath(doc) + suffix; - wps.FileSystem.Remove(l_strPath); //先删除之前可能存在的临时文件 - doc.SaveAs2(l_strPath); - l_strChangeFileName = doc.Name.split(".")[0] + suffix; - UploadFile(l_strChangeFileName, l_strPath, uploadPath, l_FieldName, OnChangeSuffixUploadSuccess, OnChangeSuffixUploadFail); - doc.SaveAs2(l_DocSourcePath); //保存回原来的文档内容 - break; - } - - wps.FileSystem.Remove(l_strPath); //上载完成后,删除临时文件 - return true; -} - -/** - * 作用:获取一个有效的临时文档路径,用于保存转换格式后的文档 - * @param {*} doc - */ -function pGetValidDocTempPath(doc) { - if (!doc) { - return; - } - if (doc.Path == "") { //对于不落地文档,文档路径为空 - return wps.Env.GetTempPath()+"/"+doc.Name.split(".")[0]; - } else { - return doc.FullName.split(".")[0] - } -} - -/** - * 作用:转格式保存上传成功后,触发这个事件的回调 - * @param {} response - */ -function OnChangeSuffixUploadSuccess(response) { - l_result = handleResultBody(response); - alert("文件转格式保存成功!"); -} - -/** - * 作用:转格式保存失败,触发失败事件回调 - * @param {*} response - */ -function OnChangeSuffixUploadFail(response) { - var l_result = ""; - l_result = handleResultBody(response); - alert("保存失败" + "\n" + +"系统返回数据:" + +JSON.stringify(l_result)); -} - -/** - * 解析返回response的参数 - * @param {*} resp - * @return {*} body - */ -function handleResultBody(resp) { - var l_result = ""; - if (resp.Body) { - //解析返回response的参数 - } - return l_result; -} - -/** - * 把OA文件的当前编辑内容,自动提交到OA后台 - */ -function pAutoUploadToServer(p_Doc) { - if (!p_Doc) { - return; - } - - /** - * 参数定义:OAAsist.UploadFile(name, path, url, field, "OnSuccess", "OnFail") - * 上传一个文件到远程服务器。 - * name:为上传后的文件名称; - * path:是文件绝对路径; - * url:为上传地址; - * field:为请求中name的值; - * 最后两个参数为回调函数名称; - */ - - var l_uploadPath = GetDocParamsValue(p_Doc, constStrEnum.uploadPath); // 文件上载路径 - if (l_uploadPath == "") { - //wps.alert("系统未传入文件上载路径,不能执行上传操作!"); - return; - } - - var l_FieldName = GetDocParamsValue(p_Doc, constStrEnum.uploadFieldName); //上载到后台的字段名称 - if (l_FieldName == "") { - l_FieldName = wps.PluginStorage.getItem(constStrEnum.DefaultUploadFieldName); // 默认为‘file’ - } - - var l_UploadName = GetDocParamsValue(p_Doc, constStrEnum.uploadFileName); //设置OA传入的文件名称参数 - if (l_UploadName == "") { - l_UploadName = p_Doc.Name; //默认文件名称就是当前文件编辑名称 - } - - var l_DocPath = p_Doc.FullName; // 文件所在路径 - - if (pIsOnlineOADoc(p_Doc) == false) { - console.log("落地文档自动保存"); - //对于本地磁盘文件上传OA,先用Save方法保存后,在上传 - //设置用户保存按钮标志,避免出现禁止OA文件保存的干扰信息 - wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.OADocSave); - p_Doc.Save(); //执行一次保存方法 - //设置用户保存按钮标志 - wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.NoneOADocSave); - //落地文档,调用UploadFile方法上传到OA后台 - try { - //调用OA助手的上传方法 - UploadFile(l_UploadName, l_DocPath, l_uploadPath, l_FieldName, OnAutoUploadSuccess, OnAutoUploadFail); - } catch (err) { - alert("上传文件失败!请检查系统上传参数及网络环境!"); - } - } else { - console.log("不落地文档自动保存"); - // 不落地的文档,调用 Document 对象的不落地上传方法 - wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.OADocSave); - try { - //调用不落地上传方法 - p_Doc.SaveAsUrl(l_UploadName, l_uploadPath, l_FieldName, "OnAutoUploadSuccess", "OnAutoUploadFail"); - } catch (err) {} - wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.NoneOADocSave); - } - -} - -/** - * 作用:自动上传到OA后台成功后出发事件 - */ -function OnAutoUploadSuccess(resp) { - return; -} - -/** - * 作用:自动上传到OA后台成功后出发事件 - */ -function OnAutoUploadFail(resp) { - return; -} - -/** - * 按照定时器的时间,自动执行所有文档的自动保存事件 - */ -function OnDocSaveByAutoTimer() { - var l_Doc; - - var l_Count = 0 - var l_docCounts = wps.WpsApplication().Documents.Count; - for (l_Count = 0; l_Count < l_docCounts; l_Count++) { - l_Doc = wps.WpsApplication().Documents.Item(l_Count); - if (l_Doc) { - if (pCheckIfOADoc(l_Doc) == true) { // 是否为OA文件 - if (pISOADocReadOnly(l_Doc) == false) { // 是否为只读文档 - //执行自动上传到OA服务器端的操作 - pAutoUploadToServer(l_Doc); - //保存该文档对应的访问过程记录信息 - } - } - } - } -} - -/** - * 实现一个定时器 - */ -function OpenTimerRun(funcCallBack) { - var l_mCount = 0; //设置一个计时器,按每分钟执行一次; 10分钟后重复执行 - var l_timeID = 0; //用于保存计时器ID值 - - // 对间隔时间做处理 - var l_AutoSaveToServerTime = wps.PluginStorage.getItem(constStrEnum.AutoSaveToServerTime); - if (l_AutoSaveToServerTime == 0) { // 设置为0则不启动定时器 - l_timeID = wps.PluginStorage.getItem(constStrEnum.TempTimerID); - clearInterval(l_timeID); - return; - } else if (l_AutoSaveToServerTime < 3) { - l_AutoSaveToServerTime = 3; - } - - l_timeID = setInterval(function() { - l_mCount = l_mCount + 1; - if (l_mCount > l_AutoSaveToServerTime) { //l_AutoSaveToServerTime 值由系统配置时设定,见pInitParameters()函数 - l_mCount = 0; - funcCallBack(); //每隔l_AutoSaveToServerTime 分钟(例如10分钟)执行一次回调函数 - } - }, 60000); //60000 每隔1分钟,执行一次操作(1000*60) - - wps.PluginStorage.setItem(constStrEnum.TempTimerID, l_timeID); //保存计时器ID值 -} - -/** - * 从OA-web端点击套红头 - * params : 需要存在以下参数 - * 'insertFileUrl':'',获取红头模板接口 - * 'bkInsertFile':'' ,正文书签 - */ -function InsertRedHead(params) { - var wpsApp = wps.WpsApplication(); - var activeDoc = wpsApp.ActiveDocument; - if (!activeDoc) { - alert('文档不存在,请先新建一个文档!'); - return; - } - - var bookmark = GetParamsValue(params, constStrEnum.bkInsertFile); - var strFile = GetParamsValue(params, constStrEnum.insertFileUrl); - if (strFile == "") { - alert("未获取到传入的红头模板URL路径,不能正常套红"); - return; - } - - if (bookmark == "") { - alert("获取到传入的正文书签,不能正常套红"); - return; - } - pInsertRInedHead(activeDoc, strFile, bookmark); -} - -/** - * 套红头 - * doc :套红头的文档 - * strFile :获取红头模板接口 - * bookmark :,正文书签 - */ -function pInsertRInedHead(doc, strFile, bookmark) { - var bookMarks = doc.Bookmarks; - if (bookMarks.Item("quanwen")) { // 当前文档存在"quanwen"书签时候表示已经套过红头 - alert("当前文档已套过红头,请勿重复操作!"); - return; - } - - var wpsApp = wps.WpsApplication(); - var activeDoc = wpsApp.ActiveDocument; - var selection = wpsApp.ActiveWindow.Selection; - // 准备以非批注的模式插入红头文件(剪切/粘贴等操作会留有痕迹,故先关闭修订) - activeDoc.TrackRevisions = false; - selection.WholeStory(); //选取全文 - bookMarks.Add("quanwen", selection.Range) - selection.Cut(); - selection.InsertFile(strFile); - if (bookMarks.Exists(bookmark)) { - var bookmark1 = bookMarks.Item(bookmark); - bookmark1.Range.Select(); //获取指定书签位置 - var s = activeDoc.ActiveWindow.Selection; - s.Paste(); - } else { - alert("套红头失败,您选择的红头模板没有对应书签:" + bookmark); - } - - // 轮询插入书签 - var elements = GetDocParamsValue(doc, constStrEnum.redFileElement); - if (elements != "") { - for (var key in elements) { - console.log(key + "----" + elements[key]) - if (bookMarks.Exists(key)) { - // 直接插入 - var eleBookmark = bookMarks.Item(key); - eleBookmark.Range.Text = elements[key]; - } - } - } - - // 恢复修订模式(根据传入参数决定) - var l_revisionCtrl = GetDocParamsValue(activeDoc, constStrEnum.revisionCtrl); - activeDoc.TrackRevisions = l_revisionCtrl == "" ? false : l_revisionCtrl.bOpenRevision; - //取消WPS关闭时的提示信息 - wps.WpsApplication().DisplayAlerts = wps.Enum&&wps.Enum.wdAlertsNone||0; -} -/** - * 从OA-web端点击套红头 - * doc : 需要存在以下属性 - * 'insertFileUrl':'',获取红头模板接口 - * 'bkInsertFile':'' ,正文书签 - */ -function InsertRedHeadDoc(doc) { //插入红头 - if (!doc) { - alert('文档不存在!'); - return; - } - - var bookmark = GetDocParamsValue(doc, constStrEnum.bkInsertFile); - var strFile = GetDocParamsValue(doc, constStrEnum.insertFileUrl); - if (strFile == "") { - alert("未获取到系统传入的红头模板URL路径,不能正常套红"); - return; - } - if (bookmark == "") { - alert("套红头失败,您选择的红头模板没有正文书签!"); - return; - } - - pInsertRInedHead(doc, strFile, bookmark) -} - -/** - * 打开本地文档,并插入文档 - */ -function OpenLocalFile() { - var l_FileName = ""; - - //msoFileDialogFilePicker = 3 - var l_FileDialog = wps.WpsApplication().FileDialog(3); - if (l_FileDialog.Show()) { - l_FileName = l_FileDialog.SelectedItems; - if (l_FileName.Count > 0) { - wps.WpsApplication().Selection.InsertFile(l_FileName.Item(1)); - } - } -} - - - -/** - * 作用:OA的正文备份按钮操作功能,把OA文件备份一份到指定的OA后台copyUrl路径中 - */ -function OnUploadOABackupClicked() { - var doc = wps.WpsApplication().ActiveDocument; - if (!doc) { - alert("当前没有打开任何文档"); - return; - } - var l_copyUrl = GetDocParamsValue(doc, constStrEnum.copyUrl); - var l_uploadFieldName = GetDocParamsValue(doc, constStrEnum.uploadFieldName); - - if (!l_copyUrl) { - alert("系统未传入备份URL路径,不能执行备份!"); - return; - } - - if (!l_uploadFieldName) { - l_uploadFieldName = "file"; - } - // 默认保存为新文档,走上传文档的接口 - UploadFile(doc.Name, doc.FullName, l_copyUrl, l_uploadFieldName, OnBackupSuccess, OnBackupFail); -} - -/** - * 备份成功后的回调 - */ -function OnBackupSuccess() { - wps.alert("备份上传成功"); -} - -/** - * 备份失败后的回调 - */ -function OnBackupFail() { - wps.alert("备份失败"); -} \ No newline at end of file diff --git a/oaassist/WpsOAAssist/js/common/func_oastarter.js b/oaassist/WpsOAAssist/js/common/func_oastarter.js deleted file mode 100644 index 1d7e2ab..0000000 --- a/oaassist/WpsOAAssist/js/common/func_oastarter.js +++ /dev/null @@ -1,146 +0,0 @@ -/** - * 在这个js中,集中处理来自OA的传入参数 - * - */ - -/** - * web页面调用WPS的方法入口 - * * info参数结构 - * info:[ - * { - * '方法名':'方法参数',需要执行的方法 - * }, - * ... - * ] - * @param {*} info - */ -let testFuncs=null; -function dispatcher(info) { - var funcs = info.funcs; - wps.WpsApplication().Options.UseLocalUserInfo=true//修订时,不使用登录名 - //解析参数 - /** - * 分两种情况解析: - * 1、业务系统依赖客户端返回:做同步处理,直接在for循环中返回 - */ - for (var index = 0; index < funcs.length; index++) { - var func = funcs[index]; - for (var key in func) { - if (key === "GetDocStatus") { - return GetDocStatus(func[key]) - } else if (key === "ExitWPS") { - ExitWPS(func[key]) - } - } - } - /** - * 2、业务系统不依赖客户端返回: - * 做异步处理,先返回接收状态,再在setTimeout中做打开文档的一系列业务逻辑 - */ - setTimeout(function(){ - for (var index = 0; index < funcs.length; index++) { - testFuncs=funcs; - var func = funcs[index]; - for (var key in func) { - func[key].isOA=true; - if (key === "OpenDoc") { // OpenDoc 属于普通的打开文档的操作方式,文档落地操作 - OpenDoc(func[key]); //进入打开文档处理函数 - } else if (key === "OnlineEditDoc") { //在线方式打开文档,属于文档不落地的方式打开 - OnlineEditDoc(func[key]); - } else if (key === "NewDoc") { - OpenDoc(func[key]); - } else if (key === "UseTemplate") { - OpenDoc(func[key]); - } else if (key === "InsertRedHead") { - InsertRedHead(func[key]); - } else if (key === "taskPaneBookMark"){ - taskPaneBookMark(func[key]) - } else if (key === "NewOfficialDocument"){ - return OpenDoc(func[key]) - } - } - } - },100) - return {message:"ok", app:wps.WpsApplication().Name} -} - - -/** - * 获取活动文档的状态 - */ -function GetDocStatus() { - let l_doc = wps.WpsApplication().ActiveDocument - if (l_doc && pCheckIfOADoc()) {//此方法还可根据需要进行扩展 - return{ - message: "GetDocStatus", - docstatus:{ - words: l_doc.Words.Count, - saved: l_doc.Saved, - pages: l_doc.ActiveWindow.Panes.Item(1).Pages.Count - } - } - } -} - -/** - * 关闭WPS活动文档并退出WPS进程 - */ -function ExitWPS() { - //为了接下来的用户确认操作,先将WPS界面激活显示在最前 - wps.WpsApplication().Activate(); - let l_doc = wps.WpsApplication().ActiveDocument - if (l_doc && pCheckIfOADoc()) {//此方法还可根据需要进行扩展 - l_doc.Close(); - } - if(wps.confirm("要关闭WPS软件,请确认文档都已保存。\n点击确定后关闭WPS,点击取消继续编辑。")){ - wps.WpsApplication().Quit(); - } -} - -/** - * - * @param {*} params OA端传入的参数 - */ -function OnlineEditDoc(OaParams) { - if (OaParams.fileName == "") { - NewFile(OaParams); - } else { - //OA传来下载文件的URL地址,调用openFile 方法打开 - OpenOnLineFile(OaParams); - } -} - -///打开来自OA端传递来的文档 -function OpenDoc(OaParams) { - if (OaParams.fileName == "") { - NewFile(OaParams); - } else { - //OA传来下载文件的URL地址,调用openFile 方法打开 - OpenFile(OaParams); - } -} - -function taskPaneBookMark(OaParams){ - let filePath = OaParams.fileName - if (filePath == "") - return - OpenFile(OaParams); - - //创建taskpane,只创建一次 - let id = wps.PluginStorage.getItem(constStrEnum.taskpaneid) - if (id){ - let tp = wps.GetTaskPane(id) - tp.Width = 300 - tp.Visible = true - } - else{ - let url = getHtmlURL("taskpane.html"); - let tp = wps.CreateTaskPane(url, "书签操作") - if (tp){ - tp.DockPosition = WPS_Enum.msoCTPDockPositionRight //这里可以设置taskapne是在左边还是右边 - tp.Width = 300 - tp.Visible = true - wps.PluginStorage.setItem(constStrEnum.taskpaneid, tp.ID) - } - } -} \ No newline at end of file diff --git a/oaassist/WpsOAAssist/js/common/func_tabcontrol.js b/oaassist/WpsOAAssist/js/common/func_tabcontrol.js deleted file mode 100644 index 0bd21d6..0000000 --- a/oaassist/WpsOAAssist/js/common/func_tabcontrol.js +++ /dev/null @@ -1,1431 +0,0 @@ -var EnumOAFlag = { - DocFromOA: 1, - DocFromNoOA: 0 -} - -//记录是否用户点击OA文件的保存按钮 -var EnumDocSaveFlag = { - OADocSave: 1, - NoneOADocSave: 0 -} - -//标识文档的落地模式 本地文档落地 0 ,不落地 1 -var EnumDocLandMode = { - DLM_LocalDoc: 0, - DLM_OnlineDoc: 1 -} - -//加载时会执行的方法 -function OnWPSWorkTabLoad(ribbonUI) { - wps.ribbonUI = ribbonUI; - if (typeof(wps.Enum) == "undefined") { // 如果没有内置枚举值 - wps.Enum = WPS_Enum; - } - OnJSWorkInit(); //初始化文档事件(全局参数,挂载监听事件) - // setTimeout(activeTab,2000); // 激活OA助手菜单 - OpenTimerRun(OnDocSaveByAutoTimer); //启动定时备份过程 - return true; -} - -//文档各类初始化工作(WPS Js环境) -function OnJSWorkInit() { - pInitParameters(); //OA助手环境的所有配置控制的初始化过程 - AddDocumentEvent(); //挂接文档事件处理函数 -} - -//初始化全局参数 -function pInitParameters() { - wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.NoneOADocSave); //初始化,没有用户点击保存按钮 - - var l_wpsUserName = wps.WpsApplication().UserName; - wps.PluginStorage.setItem(constStrEnum.WPSInitUserName, l_wpsUserName); //在OA助手加载前,先保存用户原有的WPS应用用户名称 - - wps.PluginStorage.setItem(constStrEnum.OADocCanSaveAs, false); //默认OA文档不能另存为本地 - wps.PluginStorage.setItem(constStrEnum.AllowOADocReOpen, false); //设置是否允许来自OA的文件再次被打开 - wps.PluginStorage.setItem(constStrEnum.ShowOATabDocActive, false); //设置新打开文档是否默认显示OA助手菜单Tab 默认为false - - wps.PluginStorage.setItem(constStrEnum.DefaultUploadFieldName, "file"); //针对UploadFile方法设置上载字段名称 - - wps.PluginStorage.setItem(constStrEnum.AutoSaveToServerTime, "10"); //自动保存回OA服务端的时间间隔。如果设置0,则关闭,最小设置3分钟 - wps.PluginStorage.setItem(constStrEnum.TempTimerID, "0"); //临时值,用于保存计时器ID的临时值 - - // 以下是一些临时状态参数,用于打开文档等的状态判断 - wps.PluginStorage.setItem(constStrEnum.IsInCurrOADocOpen, false); //用于执行来自OA端的新建或打开文档时的状态 - wps.PluginStorage.setItem(constStrEnum.IsInCurrOADocSaveAs, false); //用于执行来自OA端的文档另存为本地的状态 - wps.PluginStorage.setItem(constStrEnum.RevisionEnableFlag, false) //按钮的标记控制 - wps.PluginStorage.setItem(constStrEnum.Save2OAShowConfirm, true); //弹出上传成功后的提示信息 -} - -//挂载WPS的文档事件 -function AddDocumentEvent() { - wps.ApiEvent.AddApiEventListener("WindowActivate", OnWindowActivate); - wps.ApiEvent.AddApiEventListener("DocumentBeforeSave", OnDocumentBeforeSave); - wps.ApiEvent.AddApiEventListener("DocumentBeforeClose", OnDocumentBeforeClose); - wps.ApiEvent.AddApiEventListener("DocumentAfterClose", OnDocumentAfterClose); - wps.ApiEvent.AddApiEventListener("DocumentBeforePrint", OnDocumentBeforePrint); - wps.ApiEvent.AddApiEventListener("DocumentOpen", OnDocumentOpen); - wps.ApiEvent.AddApiEventListener("DocumentNew", OnDocumentNew); - // wps.ApiEvent.AddApiEventListener("NewDocument", OnDocumentNew); - console.log("AddDocumentEvent"); -} - -/** - * 打开插入书签页面 - */ -function OnInsertBookmarkToDoc() { - if (!wps.WpsApplication().ActiveDocument) { - return; - } - OnShowDialog("selectBookmark.html", "自定义书签", 700, 440, false); -} - -/** - * 作用:打开当前文档的页面设置对话框 - */ -function OnPageSetupClicked() { - var wpsApp = wps.WpsApplication(); - var doc = wpsApp.ActiveDocument; - if (!doc) { - return; - } - wpsApp.Dialogs.Item(wps.Enum&&wps.Enum.wdDialogFilePageSetup||178).Show(); -} - -/** - * 作用:打开当前文档的打印设置对话框 - */ -function OnPrintDocBtnClicked() { - var wpsApp = wps.WpsApplication(); - var doc = wpsApp.ActiveDocument; - if (!doc) { - return; - } - wpsApp.Dialogs.Item(wps.Enum&&wps.Enum.wdDialogFilePrint||88).Show(); -} - - -/** - * 作用:接受所有修订内容 - * - */ -function OnAcceptAllRevisions() { - //获取当前文档对象 - var l_Doc = wps.WpsApplication().ActiveDocument; - if (!l_Doc) { - return; - } - if (l_Doc.Revisions.Count >= 1) { - if (!wps.confirm("目前有" + l_Doc.Revisions.Count + "个修订信息,是否全部接受?")) { - return; - } - l_Doc.AcceptAllRevisions(); - } -} - - -/** - * 作用:拒绝当前文档的所有修订内容 - */ -function OnRejectAllRevisions() { - var l_Doc = wps.WpsApplication().ActiveDocument; - if (!l_Doc) { - return; - } - if (l_Doc.Revisions.Count >= 1) { - l_Doc.RejectAllRevisions(); - } -} - - -/** - * 作用:把当前文档修订模式关闭 - */ -function OnCloseRevisions() { - //获取当前文档对象 - var l_Doc = wps.WpsApplication().ActiveDocument; - OnRevisionsSwitch(l_Doc, false); -} - - -/** - * 作用:把当前文档修订模式打开 - */ -function OnOpenRevisions() { - //获取当前文档对象 - var l_Doc = wps.WpsApplication().ActiveDocument; - OnRevisionsSwitch(l_Doc, true); -} - -function OnRevisionsSwitch(doc, openRevisions) { - if (!doc) { - return; - } - var l_activeWindow = doc.ActiveWindow; - if (l_activeWindow) { - var v = l_activeWindow.View; - if (v) { - //WPS 显示使用“修订”功能对文档所作的修订和批注 - v.ShowRevisionsAndComments = openRevisions; - //WPS 显示从文本到修订和批注气球之间的连接线 - v.RevisionsBalloonShowConnectingLines = openRevisions; - } - if (openRevisions == true) { - //去掉修改痕迹信息框中的接受修订和拒绝修订勾叉,使其不可用 - wps.WpsApplication().CommandBars.ExecuteMso("KsoEx_RevisionCommentModify_Disable"); - } - - //RevisionsMode: - //wdBalloonRevisions 0 在左边距或右边距的气球中显示修订。 - //wdInLineRevisions 1 在正文中显示修订,使用删除线表示删除,使用下划线表示插入。 - // 这是 Word 早期版本的默认设置。 - //wdMixedRevisions 2 不支持。 - doc.TrackRevisions = openRevisions; // 开关修订 - l_activeWindow.ActivePane.View.RevisionsMode = 2; //2为不支持气球显示。 - - } -} - -/** - * 作用:打开扫描仪 - */ -function OnOpenScanBtnClicked() { - var doc = wps.WpsApplication().ActiveDocument; - if (!doc) { - return; - } - //打开扫描仪 - try { - wps.WpsApplication().WordBasic.InsertImagerScan(); //打开扫描仪 - } catch (err) { - alert("打开扫描仪的过程遇到问题。"); - } -} - -/** - * 作用:在文档的当前光标处插入从前端传递来的图片 - * OA参数中 picPath 是需要插入的图片路径 - * 图片插入的默认版式是在浮于文档上方 - */ -function DoInsertPicToDoc() { - console.log("DoInsertPicToDoc..."); - - var l_doc; //文档对象 - l_doc = wps.WpsApplication().ActiveDocument; - if (!l_doc) { - return; - } - - //获取当前文档对象对应的OA参数 - var l_picPath = GetDocParamsValue(l_doc, constStrEnum.picPath); // 获取OA参数传入的图片路径 - if (l_picPath == "") { - // alert("未获取到系统传入的图片URL路径,不能正常插入图片"); - // return; - //如果没有传,则默认写一个图片地址 - l_picPath="http://127.0.0.1:3888/file/OA模板公章.png" - } - - var l_picHeight = GetDocParamsValue(l_doc, constStrEnum.picHeight); //图片高 - var l_picWidth = GetDocParamsValue(l_doc, constStrEnum.picWidth); //图片宽 - - if (l_picHeight == "") { //设定图片高度 - l_picHeight = 39.117798; //13.8mm=39.117798磅 - } - if (l_picWidth == "") { //设定图片宽度 - l_picWidth = 72; //49.7mm=140.880768磅 - } - - var l_shape = l_doc.Shapes.AddPicture(l_picPath, false, true); - l_shape.Select(); - // l_shape.WrapFormat.Type = wps.Enum&&wps.Enum.wdWrapBehind||5; //图片的默认版式为浮于文字上方,可通过此设置图片环绕模式 -} -/** - * 作用:模拟插入签章图片 - * @param {*} doc 文档对象 - * @param {*} picPath 图片路径 - * @param {*} picWidth 图片宽度 - * @param {*} picHeight 图片高度 - */ -function OnInsertPicToDoc(doc, picPath, picWidth, picHeight,callBack) { - // alert("图片路径:"+picPath); - if (!doc) { - return; - } - if (typeof picPath == "undefined" || picPath == null || picPath == "") { - alert("未获取到系统传入的图片URL路径,不能正常插入印章"); - return; - } - if (!picWidth) { //设定图片宽度 - picWidth = 95; //49.7mm=140.880768磅 - } - if (!picHeight) { //设定图片高度 - picHeight = 40; //13.8mm=39.117798磅 - } - - var selection = doc.ActiveWindow.Selection; // 活动窗口选定范围或插入点 - var pagecount = doc.BuiltInDocumentProperties.Item(wps.Enum&&wps.Enum.wdPropertyPages||14); //获取文档页数 - selection.GoTo(wps.Enum&&wps.Enum.wdGoToPage||1, wps.Enum&&wps.Enum.wdGoToPage||1, pagecount.Value); //将光标指向文档最后一页 - DownloadFile(picPath,function(url){ - selection.ParagraphFormat.LineSpacing = 12 //防止文档设置了固定行距 - var picture = selection.InlineShapes.AddPicture(url, true, true); //插入图片 - wps.FileSystem.Remove(url) //删除本地的图片 - picture.LockAspectRatio = 0; //在调整形状大小时可分别改变其高度和宽度 - picture.Height = picHeight; //设定图片高度 - picture.Width = picWidth; //设定图片宽度 - picture.LockAspectRatio = 0; - picture.Select(); //当前图片为焦点 - - //定义印章图片对象 - var seal_shape = picture.ConvertToShape(); //类型转换:嵌入型图片->粘贴版型图片 - - seal_shape.RelativeHorizontalPosition = wps.Enum&&wps.Enum.wdRelativeHorizontalPositionPage||1; - seal_shape.RelativeVerticalPosition = wps.Enum&&wps.Enum.wdRelativeVerticalPositionPage||1; - seal_shape.Left = 315; //设置指定形状或形状范围的垂直位置(以磅为单位)。 - seal_shape.Top = 630; //指定形状或形状范围的水平位置(以磅为单位)。 - callBack&&callBack() - }) - -} - - - -/** - * 作用: 把当前文档保存为其他格式的文档并上传 - * @param {*} p_FileSuffix 输出的目标格式后缀名,支持:.pdf .uof .uot .ofd - * @param {*} pShowPrompt 是否弹出用户确认框 - */ -function OnDoChangeToOtherDocFormat(p_FileSuffix, pShowPrompt) { - var l_suffix = p_FileSuffix; // params.suffix; - if (!l_suffix) { - return; - } - //获取当前执行格式转换操作的文档 - var l_doc = wps.WpsApplication().ActiveDocument; - if (!l_doc) { - return; - } - console.log(pShowPrompt) - if (typeof(pShowPrompt) == "undefined") { - pShowPrompt = true; //默认设置为弹出用户确认框 - } - //默认设置为以当前文件的显示模式输出,即当前为修订则输出带有修订痕迹的 - pDoChangeToOtherDocFormat(l_doc, l_suffix, pShowPrompt, true); -} -/** - * 作用:获取文档的Path或者临时文件路径 - * @param {*} doc - */ - function getDocSavePath(doc) { - if (!doc) { - return; - } - if (doc.Path == "") { //对于不落地文档,文档路径为空 - return wps.Env.GetTempPath(); - } else { - return doc.Path - } -} -/** - * 作用:把当前文档输出为另外的格式保存 - * @param {*} p_Doc 文档对象 - * @param {*} p_Suffix 另存为的目标文件格式 - * @param {*} pShowPrompt 是否弹出用户确认框 - * @param {*} p_ShowRevision :是否强制关闭修订,如果是False,则强制关闭痕迹显示。如果为true则不做控制输出。 - */ -function pDoChangeToOtherDocFormat(p_Doc, p_Suffix, pShowPrompt, p_ShowRevision) { - if (!p_Doc) { - return; - } - - var l_suffix = p_Suffix; - //获取该文档对应OA参数的上载路径 - var l_uploadPath = GetDocParamsValue(p_Doc, constStrEnum.uploadAppendPath); - if (l_uploadPath == "" || l_uploadPath == null) { - l_uploadPath = GetDocParamsValue(p_Doc, constStrEnum.uploadPath); - } - var l_FieldName = GetDocParamsValue(p_Doc, constStrEnum.uploadFieldName); - if (l_FieldName == "") { - l_FieldName = wps.PluginStorage.getItem(constStrEnum.DefaultUploadFieldName); //默认是'file' - } - - if (l_uploadPath == "" && pShowPrompt == true) { - alert("系统未传入有效上载文件路径!不能继续转换操作。"); //如果OA未传入上载路径,则给予提示 - return; - } - - if (pShowPrompt == true) { - if (!wps.confirm("当前文档将另存一份" + l_suffix + " 格式的副本,并上传到系统后台,请确认 ?")) { - return; - } - } - - // 先把文档输出保存为指定的文件格式,再上传到后台 - wps.PluginStorage.setItem(constStrEnum.OADocUserSave, true); //设置一个临时变量,用于在BeforeSave事件中判断 - if (p_ShowRevision == false) { // 强制关闭痕迹显示 - var l_SourceName = p_Doc.Name; - var l_NewName=""; - var docPath=getDocSavePath(p_Doc); - if(docPath.indexOf("\\")>0){ - l_NewName = docPath + "\\B_" + p_Doc.Name; - }else{ - l_NewName = docPath + "/B_" + p_Doc.Name; - } - if(docPath.indexOf("\\")>0){ - l_SourceName = docPath + "\\" + l_SourceName; - }else{ - l_SourceName = docPath + "/" + l_SourceName; - } - - p_Doc.SaveAs2($FileName = l_NewName, $AddToRecentFiles = false); - p_Doc.SaveAs2($FileName = l_SourceName, $AddToRecentFiles = false); - //以下以隐藏模式打开另一个文档 - var l_textEncoding = wps.WpsApplication().Options.DefaultTextEncoding; //默认 936 - var l_Doc = wps.WpsApplication().Documents.Open(l_NewName, false, false, false, "", "", false, "", "", 0, l_textEncoding, false); - - l_Doc.TrackRevisions = false; //关闭修订模式 - l_Doc.ShowRevisions = false; //隐含属性,隐藏修订模式 - l_Doc.AcceptAllRevisions(); - l_Doc.Save(); - handleFileAndUpload(l_suffix, l_Doc, l_uploadPath, l_FieldName); - l_Doc.Close(); - wps.FileSystem.Remove(l_NewName); //删除临时文档 - } else { - handleFileAndUpload(l_suffix, p_Doc, l_uploadPath, l_FieldName); - } - - wps.PluginStorage.setItem(constStrEnum.OADocUserSave, false); - - return; -} - -/** - * 把文档转换成UOT在上传 - */ -function OnDoChangeToUOF() {} - -/** - * 打开WPS云文档的入口 - */ -function pDoOpenWPSCloundDoc() { - wps.TabPages.Add("https://www.kdocs.cn"); -} - -/** - * 执行另存为本地文件操作 - */ -function OnBtnSaveAsLocalFile() { - - //初始化临时状态值 - wps.PluginStorage.setItem(constStrEnum.OADocUserSave, false); - wps.PluginStorage.setItem(constStrEnum.IsInCurrOADocSaveAs, false); - - //检测是否有文档正在处理 - var l_doc = wps.WpsApplication().ActiveDocument; - if (!l_doc) { - alert("WPS当前没有可操作文档!"); - return; - } - - // 设置WPS文档对话框 2 FileDialogType:=msoFileDialogSaveAs - var l_ksoFileDialog = wps.WpsApplication().FileDialog(2); - l_ksoFileDialog.InitialFileName = l_doc.Name; //文档名称 - - if (l_ksoFileDialog.Show() == -1) { // -1 代表确认按钮 - //alert("确认"); - wps.PluginStorage.setItem(constStrEnum.OADocUserSave, true); //设置保存为临时状态,在Save事件中避免OA禁止另存为对话框 - l_ksoFileDialog.Execute(); //会触发保存文档的监听函数 - - pSetNoneOADocFlag(l_doc); - - wps.ribbonUI.Invalidate(); //刷新Ribbon的状态 - - }; -} - -// -/** - * 作用:执行清稿按钮操作 - * 业务功能:清除所有修订痕迹和批注 - */ -function OnBtnClearRevDoc() { - var doc = wps.WpsApplication().ActiveDocument; - if (!doc) { - alert("尚未打开文档,请先打开文档再进行清稿操作!"); - } - - //执行清稿操作前,给用户提示 - if (!wps.confirm("清稿操作将接受所有的修订内容,关闭修订显示。请确认执行清稿操作?")) { - return; - } - - //接受所有修订 - if (doc.Revisions.Count >= 1) { - doc.AcceptAllRevisions(); - } - //去除所有批注 - if (doc.Comments.Count >= 1) { - doc.RemoveDocumentInformation(wps.Enum&&wps.Enum.wdRDIComments||1); - } - - //删除所有ink墨迹对象 - pDeleteAllInkObj(doc); - - doc.TrackRevisions = false; //关闭修订模式 - wps.ribbonUI.InvalidateControl("btnOpenRevision"); - - return; -} - -/** - * 作用:删除当前文档的所有墨迹对象 - * @param {*} p_Doc - */ -function pDeleteAllInkObj(p_Doc) { - var l_Count = 0; - var l_IsInkObjExist = true; - while (l_IsInkObjExist == true && l_Count < 20) { - l_IsInkObjExist = pDeleteInkObj(p_Doc); - l_Count++; - } - return; -} - -/** - * 删除墨迹对象 - */ -function pDeleteInkObj(p_Doc) { - var l_IsInkObjExist = false; - if (p_Doc) { - for (var l_Index = 1; l_Index <= p_Doc.Shapes.Count; l_Index++) { - var l_Item = p_Doc.Shapes.Item(l_Index); - if (l_Item.Type == 23) { - l_Item.Delete(); - //只要有一次找到Ink类型,就标识一下 - if (l_IsInkObjExist == false) { - l_IsInkObjExist = true; - } - } - } - } - return l_IsInkObjExist; -} - - -/** - * - */ -function pSaveAnotherDoc(p_Doc) { - if (!p_Doc) { - return; - } - var l_SourceDocName = p_Doc.Name; - var l_NewName = "BK_" + l_SourceDocName; - p_Doc.SaveAs2(l_NewName); - wps.WpsApplication().Documents.Open(); -} - - -//保存到OA后台服务器 -function OnBtnSaveToServer() { - // console.log('SaveToServer'); - var l_doc = wps.WpsApplication().ActiveDocument; - if (!l_doc) { - alert("空文档不能保存!"); - return; - } - - //非OA文档,不能上传到OA - if (pCheckIfOADoc() == false) { - alert("非系统打开的文档,不能直接上传到系统!"); - return; - } - - //如果是OA打开的文档,并且设置了保护的文档,则不能再上传到OA服务器 - if (pISOADocReadOnly(l_doc)) { - wps.alert("系统设置了保护的文档,不能再提交到系统后台。"); - return; - } - - /** - * 参数定义:OAAsist.UploadFile(name, path, url, field, "OnSuccess", "OnFail") - * 上传一个文件到远程服务器。 - * name:为上传后的文件名称; - * path:是文件绝对路径; - * url:为上传地址; - * field:为请求中name的值; - * 最后两个参数为回调函数名称; - */ - var l_uploadPath = GetDocParamsValue(l_doc, constStrEnum.uploadPath); // 文件上载路径 - if (l_uploadPath == "") { - wps.alert("系统未传入文件上载路径,不能执行上传操作!"); - return; - } - - var l_showConfirm = wps.PluginStorage.getItem(constStrEnum.Save2OAShowConfirm) - if (l_showConfirm) { - if (!wps.confirm("先保存文档,并开始上传到系统后台,请确认?")) { - return; - } - } - - var l_FieldName = GetDocParamsValue(l_doc, constStrEnum.uploadFieldName); //上载到后台的业务方自定义的字段名称 - if (l_FieldName == "") { - l_FieldName = wps.PluginStorage.getItem(constStrEnum.DefaultUploadFieldName); // 默认为‘file’ - } - - var l_UploadName = GetDocParamsValue(l_doc, constStrEnum.uploadFileName); //设置OA传入的文件名称参数 - if (l_UploadName == "") { - l_UploadName = l_doc.Name; //默认文件名称就是当前文件编辑名称 - } - - var l_DocPath = l_doc.FullName; // 文件所在路径 - - if (pIsOnlineOADoc(l_doc) == false) { - //对于本地磁盘文件上传OA,先用Save方法保存后,再上传 - //设置用户保存按钮标志,避免出现禁止OA文件保存的干扰信息 - wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.OADocSave); - if (l_doc.Path == "") { //对于不落地文档,文档路径为空 - l_doc.SaveAs2(wps.Env.GetTempPath() + "/" + l_doc.Name, undefined, undefined, undefined, false); - } else { - l_doc.Save(); - } - //执行一次保存方法 - //设置用户保存按钮标志 - wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.NoneOADocSave); - //落地文档,调用UploadFile方法上传到OA后台 - l_DocPath = l_doc.FullName; - try { - //调用OA助手的上传方法 - UploadFile(l_UploadName, l_DocPath, l_uploadPath, l_FieldName, OnUploadToServerSuccess, OnUploadToServerFail); - } catch (err) { - alert("上传文件失败!请检查系统上传参数及网络环境!"); - } - } else { - // 不落地的文档,调用 Document 对象的不落地上传方法 - wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.OADocSave); - try { - //调用不落地上传方法 - l_doc.SaveAsUrl(l_UploadName, l_uploadPath, l_FieldName, "OnUploadToServerSuccess", "OnUploadToServerFail"); - } catch (err) { - alert("上传文件失败!请检查系统上传参数及网络环境,重新上传。"); - } - wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.NoneOADocSave); - } - - //获取OA传入的 转其他格式上传属性 - var l_suffix = GetDocParamsValue(l_doc, constStrEnum.suffix); - if (l_suffix == "") { - console.log("上传需转换的文件后缀名错误,无法进行转换上传!"); - return; - } - - //判断是否同时上传PDF等格式到OA后台 - var l_uploadWithAppendPath = GetDocParamsValue(l_doc, constStrEnum.uploadWithAppendPath); //标识是否同时上传suffix格式的文档 - if (l_uploadWithAppendPath == "1") { - //调用转pdf格式函数,强制关闭转换修订痕迹,不弹出用户确认的对话框 - pDoChangeToOtherDocFormat(l_doc, l_suffix, false, false); - } - return; -} - - -/** - * 作用:套红头 - * 所有与OA系统相关的业务功能,都放在oabuss 子目录下 - */ -function OnInsertRedHeaderClick() { - var l_Doc = wps.WpsApplication().ActiveDocument; - if (!l_Doc) { - return; - } - var l_insertFileUrl = GetDocParamsValue(l_Doc, constStrEnum.insertFileUrl); //插入文件的位置 - var l_BkFile = GetDocParamsValue(l_Doc, constStrEnum.bkInsertFile); - if (l_BkFile == "" || l_insertFileUrl == "") { - var height = 250; - var width = 400; - OnShowDialog("redhead.html", "OA助手", width, height); - return; - } - InsertRedHeadDoc(l_Doc); -} - - -/** - * 插入时间 - * params参数结构 - * params:{ - * - * } - */ -function OnInsertDateClicked() { - var l_Doc = wps.WpsApplication().ActiveDocument; - if (l_Doc) { - //打开插入日期对话框 - wps.WpsApplication().Dialogs.Item(wps.Enum&&wps.Enum.wdDialogInsertDateTime||165).Show(); - } -} - - -/** - * 调用文件上传到OA服务端时, - * @param {*} resp - */ -function OnUploadToServerSuccess(resp) { - console.log("成功上传服务端后的回调:" + resp) - console.log(resp) - var l_doc = wps.WpsApplication().ActiveDocument; - var l_showConfirm = wps.PluginStorage.getItem(constStrEnum.Save2OAShowConfirm); - if (l_showConfirm) { - if (wps.confirm("文件上传成功!继续编辑请确认,取消关闭文档。") == false) { - if (l_doc) { - console.log("OnUploadToServerSuccess: before Close"); - l_doc.Close(-1); //保存文档后关闭 - console.log("OnUploadToServerSuccess: after Close"); - } - } - } - - var l_NofityURL = GetDocParamsValue(l_doc, constStrEnum.notifyUrl); - if (l_NofityURL != "") { - l_NofityURL = l_NofityURL.replace("{?}", "2"); //约定:参数为2则文档被成功上传 - NotifyToServer(l_NofityURL); - } -} - -function OnUploadToServerFail(resp) { - alert("文件上传失败!"); -} - -function OnbtnTabClick() { - alert("OnbtnTabClick"); -} - - - -//判断当前文档是否是OA文档 -function pCheckIfOADoc() { - var doc = wps.WpsApplication().ActiveDocument; - if (!doc) - return false; - return CheckIfDocIsOADoc(doc); -} - -//根据传入的doc对象,判断当前文档是否是OA文档 -function CheckIfDocIsOADoc(doc) { - if (!doc) { - return false; - } - - var l_isOA = GetDocParamsValue(doc, constStrEnum.isOA); - if (l_isOA == "") { - return false - }; - - return l_isOA == EnumOAFlag.DocFromOA ? true : false; -} - -//获取文件来源标识 -function pGetDocSourceLabel() { - return pCheckIfOADoc() ? "OA文件" : "非OA文件"; -} - - - -/** - * 作用:设置用户名称标签 - */ -function pSetUserNameLabelControl() { - var l_doc = wps.WpsApplication().ActiveDocument; - if (!l_doc) return ""; - - var l_strUserName = ""; - if (pCheckIfOADoc() == true) { // OA文档,获取OA用户名 - var userName = GetDocParamsValue(l_doc, constStrEnum.userName); - l_strUserName = userName == "" ? "未设置" : userName; - } else { - //非OA传来的文档,则按WPS安装后设置的用户名显示 - l_strUserName = "" + wps.PluginStorage.getItem(constStrEnum.WPSInitUserName); - } - - return l_strUserName; -} - - -/** - * 作用:判断是否是不落地文档 - * 参数:doc 文档对象 - * 返回值: 布尔值 - */ -function pIsOnlineOADoc(doc) { - var l_LandMode = GetDocParamsValue(doc, constStrEnum.OADocLandMode); //获取文档落地模式 - if (l_LandMode == "") { //用户本地打开的文档 - return false; - } - return l_LandMode == EnumDocLandMode.DLM_OnlineDoc; -} -/** - * 作用:返回OA文档落地模式标签 - */ -function pGetOADocLabel() { - var l_Doc = wps.WpsApplication().ActiveDocument; - if (!l_Doc) { - return ""; - } - - var l_strLabel = ""; //初始化 - - if (pIsOnlineOADoc(l_Doc) == true) { // 判断是否为不落地文档 - l_strLabel = "文档状态:不落地"; - } else { - l_strLabel = l_Doc.Path != "" ? "文档状态:落地" : "文档状态:未保存"; - } - - //判断OA文档是否是受保护 - if (pISOADocReadOnly(l_Doc) == true) { - l_strLabel = l_strLabel + "(保护)"; - } - return l_strLabel; -} - -//返回是否可以点击OA保存按钮的状态 -function OnSetSaveToOAEnable() { - return pCheckIfOADoc(); -} - - -/** - * 作用:根据OA传入参数,设置是否显示Ribbob按钮组 - * 参数:CtrlID 是OnGetVisible 传入的Ribbob控件的ID值 - */ -function pShowRibbonGroupByOADocParam(CtrlID) { - var l_Doc = wps.WpsApplication().ActiveDocument; - if (!l_Doc) { - return false; //如果未装入文档,则设置OA助手按钮组不可见 - } - - //获取OA传入的按钮组参数组 - var l_grpButtonParams = GetDocParamsValue(l_Doc, constStrEnum.buttonGroups); //disableBtns - l_grpButtonParams = l_grpButtonParams + "," + GetDocParamsValue(l_Doc, constStrEnum.disableBtns); - - - // 要求OA传入控制自定义按钮显示的参数为字符串 中间用 , 分隔开 - if (typeof(l_grpButtonParams) == "string") { - var l_arrayGroup = new Array(); - l_arrayGroup = l_grpButtonParams.split(","); - //console.log(l_grpButtonParams); - - // 判断当前按钮是否存在于数组 - if (l_arrayGroup.indexOf(CtrlID) >= 0) { - return false; - } - } - // 添加OA菜单判断 - if (CtrlID == "WPSWorkExtTab") { - if(wps.WpsApplication().ActiveDocument){ - let l_value=GetDocParamsValue(wps.WpsApplication().ActiveDocument,"isOA"); - return l_value?true:false; - } - var l_value = wps.PluginStorage.getItem(constStrEnum.ShowOATabDocActive); - wps.PluginStorage.setItem(constStrEnum.ShowOATabDocActive, false); //初始化临时状态变量 - console.log("菜单:" + l_value); - return l_value; - } - return true; -} - -/** - * 根据传入Document对象,获取OA传入的参数的某个Key值的Value - * @param {*} Doc - * @param {*} Key - * 返回值:返回指定 Key的 Value - */ -function GetDocParamsValue(Doc, Key) { - if (!Doc) { - return ""; - } - - var l_Params = wps.PluginStorage.getItem(Doc.DocID); - if (!l_Params) { - return ""; - } - - var l_objParams = JSON.parse(l_Params); - if (typeof(l_objParams) == "undefined") { - return ""; - } - - var l_rtnValue = l_objParams[Key]; - if (typeof(l_rtnValue) == "undefined" || l_rtnValue == null) { - return ""; - } - return l_rtnValue; -} - -/** - * 获取对象中指定属性的值 - * @param {*} params - * @param {*} Key - */ -function GetParamsValue(Params, Key) { - if (typeof(Params) == "undefined") { - return ""; - } - - var l_rtnValue = Params[Key]; - return l_rtnValue; -} - - - -/** - * 作用:插入二维码图片 - */ -function OnInsertQRCode() { - OnShowDialog("QRCode.html", "插入二维码", 400, 400); -} - - -/** - * 打开本地文档并插入到当前文档中指定位置(导入文档) - */ -function OnOpenLocalFile() { - OpenLocalFile(); -} -/** - * 插入水印 - */ -function DoInsertWaterToDoc(){ -    var app, shapeRange; -    try { -        // app = wpsFrame.Application; -        var app=wps.WpsApplication(); -        var doc = app.ActiveDocument; -        var selection = doc.ActiveWindow.Selection; -        var pageCount = app.ActiveWindow.ActivePane.Pages.Count; -        for(var i=1;i<=pageCount;i++){ -            selection.GoTo(1, 1, i); - app.ActiveWindow.ActivePane.View.SeekView=9; -            app.ActiveDocument.Sections.Item(1).Headers.Item(1).Shapes.AddTextEffect(0, "公司绝密", "华文新魏", 36, false, false, 0, 0).Select(); -            shapeRange = app.Selection.ShapeRange; -            shapeRange.TextEffect.NormalizedHeight = false; -            shapeRange.Line.Visible = false; -            shapeRange.Fill.Visible = true; -            shapeRange.Fill.Solid(); -            shapeRange.Fill.ForeColor.RGB = 12632256;       /* WdColor枚举 wdColorGray25 代表颜色值 */ -            shapeRange.Fill.Transparency = 0.5;             /* 填充透明度,值为0.0~1.0 */ -            shapeRange.LockAspectRatio = true; -            shapeRange.Height = 4.58 * 28.346; -            shapeRange.Width = 28.07 * 28.346; -            shapeRange.Rotation = 315;                      /* 图形按照Z轴旋转度数,正值为顺时针旋转,负值为逆时针旋转 */ -            shapeRange.WrapFormat.AllowOverlap = true; -            shapeRange.WrapFormat.Side = 3;                 /* WdWrapSideType枚举 wdWrapLargest 形状距离页边距最远的一侧 */ -            shapeRange.WrapFormat.Type = 3;                  -            shapeRange.RelativeHorizontalPosition = 0;       -            shapeRange.RelativeVerticalPosition = 0;         -            shapeRange.Left = '-999995';                    -            shapeRange.Top = '-999995';                      -            -        }                  /* WdShapePosition枚举 wdShapeCenter 形状的位置在中央 */ -        selection.GoTo(1, 1, 1); - app.ActiveWindow.ActivePane.View.SeekView=0; -    } catch (error) { -        alert(error.message); -    } -} - -/** - * 插入电子印章的功能 - */ -function OnInsertSeal() { - OnShowDialog("selectSeal.html", "印章", 730, 500); -} - -/** - * 导入模板到文档中 - */ -function OnImportTemplate() { - OnShowDialog("importTemplate.html", "导入模板", 560, 400); -} - - -//自定义菜单按钮的点击执行事件 -function OnAction(control) { - var eleId; - if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 - eleId = control.Id; - } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 - eleId = arguments[1].Id; - console.log(eleId) - } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 - eleId = arguments[1].Id; - } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 - eleId = arguments[2].Id; - } - switch (eleId) { - case "btnOpenWPSYUN": //打开WPS云文档入口 - pDoOpenWPSCloundDoc(); - break; - case "btnOpenLocalWPSYUN": //打开本地文档并插入到文档中 - OnOpenLocalFile(); - break; - case "WPSWorkExtTab": - OnbtnTabClick(); - break; - case "btnSaveToServer": //保存到OA服务器 - wps.PluginStorage.setItem(constStrEnum.Save2OAShowConfirm, true) - OnBtnSaveToServer(); - break; - case "btnSaveAsFile": //另存为本地文件 - OnBtnSaveAsLocalFile(); - break; - case "btnChangeToPDF": //转PDF文档并上传 - OnDoChangeToOtherDocFormat(".pdf"); - break; - case "btnChangeToUOT": //转UOF文档并上传 - OnDoChangeToOtherDocFormat(".uof"); - break; - case "btnChangeToOFD": //转OFD文档并上传 - OnDoChangeToOtherDocFormat(".ofd"); - break; - //------------------------------------ - case "btnInsertRedHeader": //插入红头 - OnInsertRedHeaderClick(); //套红头功能 - break; - case "btnUploadOABackup": //文件备份 - OnUploadOABackupClicked(); - break; - case "btnInsertSeal": //插入印章 - OnInsertSeal(); - break; - //------------------------------------ - //修订按钮组 - case "btnClearRevDoc": //执行 清稿 按钮 - OnBtnClearRevDoc(); - break; - case "btnOpenRevision": //打开修订 - { - let bFlag = wps.PluginStorage.getItem(constStrEnum.RevisionEnableFlag) - wps.PluginStorage.setItem(constStrEnum.RevisionEnableFlag, !bFlag) - //通知wps刷新以下几个按钮的状态 - wps.ribbonUI.InvalidateControl("btnOpenRevision") - wps.ribbonUI.InvalidateControl("btnCloseRevision") - OnOpenRevisions(); // - break; - } - case "btnCloseRevision": //关闭修订 - { - let bFlag = wps.PluginStorage.getItem(constStrEnum.RevisionEnableFlag) - wps.PluginStorage.setItem(constStrEnum.RevisionEnableFlag, !bFlag) - //通知wps刷新以下几个按钮的状态 - wps.ribbonUI.InvalidateControl("btnOpenRevision") - wps.ribbonUI.InvalidateControl("btnCloseRevision") - OnCloseRevisions(); - break; - } - case "btnShowRevision": - break; - case "btnAcceptAllRevisions": //接受所有修订功能 - OnAcceptAllRevisions(); - break; - case "btnRejectAllRevisions": //拒绝修订 - OnRejectAllRevisions(); - break; - //------------------------------------ - case "btnInsertPic": //插入图片 - DoInsertPicToDoc(); - break; - case "btnInsertWater": - DoInsertWaterToDoc() - case "btnInsertDate": //插入日期 - OnInsertDateClicked(); - break; - case "btnOpenScan": //打开扫描仪 - OnOpenScanBtnClicked(); - break; - case "btnPageSetup": //打开页面设置 - OnPageSetupClicked(); - break; - case "btnQRCode": //插入二维码 - OnInsertQRCode(); // - break; - case "btnPrintDOC": // 打开打印设置 - OnPrintDocBtnClicked(); - break; - case "lblDocSourceValue": //OA公文提示 - OnOADocInfo(); - break; - case "btnUserName": //点击用户 - OnUserNameSetClick(); - break; - case "btnInsertBookmark": //插入书签 - OnInsertBookmarkToDoc(); - break; - case "btnImportTemplate": //导入模板 - OnImportTemplate(); - break; - case "FileSaveAsMenu": //通过idMso进行「另存为」功能的自定义 - case "FileSaveAs": - { - if (pCheckIfOADoc()) { //文档来源是业务系统的,做自定义 - alert("这是OA文档,将Ctrl+S动作做了重定义,可以调用OA的保存文件流到业务系统的接口。") - OnBtnSaveToServer(); - } else { //本地的文档,期望不做自定义,通过转调idMso的方法实现 - wps.WpsApplication().CommandBars.ExecuteMso("FileSaveAsWordDocx"); - //此处一定不能去调用与重写idMso相同的ID,否则就是个无线递归了,即在这个场景下不可调用FileSaveAs和FileSaveAsMenu这两个方法 - } - break; - } - case "FileSave": //通过idMso进行「保存」功能的自定义 - { - if (pCheckIfOADoc()) { //文档来源是业务系统的,做自定义 - alert("这是OA文档,将Ctrl+S动作做了重定义,可以调用OA的保存文件流到业务系统的接口。") - OnBtnSaveToServer(); - } else { //本地的文档,期望不做自定义,通过转调idMso的方法实现 - // wps.WpsApplication().CommandBars.ExecuteMso("FileSave"); - wps.WpsApplication().CommandBars.ExecuteMso("SaveAll"); - //此处一定不能去调用与重写idMso相同的ID,否则就是个无线递归了,即在这个场景下不可调用FileSaveAs和FileSaveAsMenu这两个方法 - } - break; - } - case "FileNew": - case "FileNewMenu": - case "WindowNew": - case "FileNewBlankDocument": - { - if (pCheckIfOADoc()) { //文档来源是业务系统的,做自定义 - alert("这是OA文档,将Ctrl+N动作做了禁用") - } - } - break - case "ShowAlert_ContextMenuText": - { - let selectText = wps.WpsApplication().Selection.Text; - alert("您选择的内容是:\n" + selectText); - break; - } - case "btnSendMessage1": - { - /** - * 内部封装了主动响应前端发送的请求的方法 - */ - //参数自定义,这里只是负责传递参数,在WpsInvoke.RegWebNotify方法的回调函数中去做接收,自行解析参数 - let params={ - type:'executeFunc1', - message:"当前时间为:" + currentTime() - } - /** - * WebNotify: - * 参数1:发送给业务系统的消息 - * 参数2:是否将消息加入队列,是否防止丢失消息,都需要设置为true - */ - wps.OAAssist.WebNotify(JSON.stringify(params),true); //如果想传一个对象,则使用JSON.stringify方法转成对象字符串。 - break; - } - case "btnSendMessage2": - { - /** - * 内部封装了主动响应前端发送的请求的方法 - */ - let msgInfo = - { - id: 1, - name: 'kingsoft', - since: "1988" - } - //参数自定义,这里只是负责传递参数,在WpsInvoke.RegWebNotify方法的回调函数中去做接收,自行解析参数 - - let params={ - type:'executeFunc2', - message:"当前时间为:" + currentTime(), - msgInfoStr: JSON.stringify(msgInfo) - } - /** - * WebNotify: - * 参数1:发送给业务系统的消息 - * 参数2:是否将消息加入队列,是否防止丢失消息,都需要设置为true - */ - wps.OAAssist.WebNotify(JSON.stringify(params),true); //如果想传一个对象,则使用JSON.stringify方法转成对象字符串。 - break; - } - case "btnAddWebShape": - { - let l_doc = wps.WpsApplication().ActiveDocument; - l_doc.Shapes.AddWebShape("https://www.wps.cn"); - break; - } - default: - break; - } - return true; -} - -/** - * 作用:重新设置当前用户名称 - */ -function OnUserNameSetClick() { - var l_UserPageUrl = "setUserName.html" - OnShowDialog(l_UserPageUrl, "OA助手用户名称设置", 500, 300); -} -/** - * 作用:展示当前文档,被OA助手打开后的,操作记录及相关附加信息 - */ -function OnOADocInfo() { - return; -} - -/** - * 作用:自定义菜单按钮的图标 - */ -function GetImage(control) { - var eleId; - if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 - eleId = control.Id; - } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 - eleId = arguments[1].Id; - } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 - eleId = arguments[1].Id; - } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 - eleId = arguments[2].Id; - } - switch (eleId) { - case "btnOpenWPSYUN": - return "./icon/w_WPSCloud.png"; //打开WPS云文档 - case "btnOpenLocalWPSYUN": //导入文件 - return "./icon/w_ImportDoc.png" - case "btnSaveToServer": //保存到OA后台服务端 - return "./icon/w_Save.png"; - case "btnSaveAsFile": //另存为本地文件 - return "./icon/w_SaveAs.png"; - case "btnChangeToPDF": //输出为PDF格式 - return "./icon/w_PDF.png"; - case "btnChangeToUOT": // - return "./icon/w_DocUOF.png"; - case "btnChangeToOFD": //转OFD上传 - return "./icon/w_DocOFD.png"; // - case "btnInsertRedHeader": //套红头 - return "./icon/w_GovDoc.png"; - case "btnInsertSeal": //印章 - return "./icon/c_seal.png"; - case "btnClearRevDoc": //清稿 - return "./icon/w_DocClear.png" - case "btnUploadOABackup": //备份正文 - return "./icon/w_BackDoc.png"; - case "btnOpenRevision": //打开 修订 - case "btnShowRevision": // - return "./icon/w_OpenRev.png"; - case "btnCloseRevision": //关闭修订 - return "./icon/w_CloseRev.png"; - case "btnAcceptAllRevisions": // 接受修订 - return "./icon/w_AcceptRev.png"; - case "btnRejectAllRevisions": // 拒绝修订 - return "./icon/w_RejectRev.png"; - case "btnSaveAsFile": - return ""; - case "btnInsertWater": - case "btnInsertPic": //插入图片 - return "./icon/w_InsPictures.png"; - case "btnOpenScan": //打开扫描仪 - return "./icon/w_Scanner16.png"; // - case "btnPageSetup": //打开页面设置 - return "./icon/w_PageGear.png"; - case "btnInsertDate": //插入日期 - return "./icon/w_InsDate.png"; - case "btnQRCode": //二维码 - return "./icon/w_DocQr.png"; - case "btnPrintDOC": // 打印设置 - return "./icon/c_printDoc.png"; - case "btnInsertBookmark": - return "./icon/c_bookmark.png"; - case "btnImportTemplate": - return "./icon/w_ImportDoc.png"; - case "btnSendMessage1": - return "./icon/3.svg" - case "btnSendMessage2": - return "./icon/3.svg" - default: - ; - } - return "./icon/c_default.png"; -} - -function pGetOpenRevisionButtonLabel() { - return "打开修订"; -} - -function pGetShowRevisionButtonLabel() { - return "显示修订"; -} - - -//xml文件中自定义按钮的文字处理函数 -function OnGetLabel(control) { - var eleId; - if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 - eleId = control.Id; - } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 - eleId = arguments[1].Id; - } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 - eleId = arguments[1].Id; - } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 - eleId = arguments[2].Id; - } - switch (eleId) { - case "btnOpenWPSYUN": //打开WPS云文档 - return "WPS云文档"; - case "btnOpenLocalWPSYUN": //打开本地云文档目录 - return "导入文档"; - case "btnSaveAsFile": - return "另存为本地"; - case "btnChangeToPDF": //转PDF并上传 - return "转PDF上传"; - case "btnChangeToUOT": //转UOF并上传 - return "转UOF上传"; - case "btnChangeToOFD": //转OFD格式并上传 - return "转OFD上传"; - case "lblDocSourceValue": //文件来源标签: - return pGetDocSourceLabel(); - case "lblUserName": //用户名:lableControl 控件 - return "编辑人:"; //pSetUserNameLabelControl(); - case "btnUserName": - return pSetUserNameLabelControl(); - //====================================================== - case "btnInsertRedHeader": //套红头 - return "套红头"; - case "btnInsertSeal": //插入印章 - return "印章"; - case "btnUploadOABackup": //文件备份 - return "文件备份"; - //====================================================== - case "btnOpenRevision": //打开修订按钮 - return pGetOpenRevisionButtonLabel(); - case "btnShowRevision": //显示修订按钮 - return pGetShowRevisionButtonLabel(); - case "btnCloseRevision": //关闭修订按钮 - return "关闭修订"; - case "btnClearRevDoc": //显示 清稿 - return "清稿"; - case "btnAcceptAllRevisions": //显示 接受修订 - return "接受修订"; - case "btnRejectAllRevisions": //显示 拒绝修订 - return "拒绝修订"; - case "lblDocLandMode": //显示 文档落地方式 :不落地还是本地,包括是否受保护 - return pGetOADocLabel(); - //--------------------------------------------- - case "btnInsertPic": //插入图片 - return "插图片"; - case "btnInsertDate": //插入日期 - return "插日期"; - case "btnOpenScan": //打开扫描仪 - return "扫描仪"; - case "btnInsertWater": - return "插入水印" - case "btnPageSetup": //打开页面设置 - return "页面设置"; - case "btnPrintDOC": //打开页面设置 - return "打印设置"; - case "btnInsertBookmark": - return "导入书签"; - case "btnImportTemplate": - return "导入模板"; - default: - ; - } - return ""; -} - -/** - * 作用:处理Ribbon按钮的是否可显示 - * @param {*} control :Ribbon 的按钮控件 - */ -function OnGetVisible(control) { - var eleId; - if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 - eleId = control.Id; - } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 - eleId = arguments[1].Id; - } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 - eleId = arguments[1].Id; - } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 - eleId = arguments[2].Id; - } - var l_value = false; - - //关闭一些测试中的功能 - switch (eleId) { - case "lblDocLandMode": //文档落地标签 - return true; - case "btnOpenScan": - return false; - case "btnAddWebShape": - { - if (wps.WpsApplication().Build.toString().indexOf("11.1") != -1){ - return true; - } - return false; - } - break; - default: - - } - - //按照 OA文档传递过来的属性进行判断 - l_value = pShowRibbonGroupByOADocParam(eleId); - return l_value; -} - -/** - * 作用:处理Ribbon按钮的是否可用 - * @param {*} control :Ribbon 的按钮控件 - */ -function OnGetEnabled(control) { - var eleId; - if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 - eleId = control.Id; - } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 - eleId = arguments[1].Id; - } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 - eleId = arguments[1].Id; - } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 - eleId = arguments[2].Id; - } - switch (eleId) { - case "btnSaveToServer": //保存到OA服务器的相关按钮。判断,如果非OA文件,禁止点击 - case "btnChangeToPDF": //保存到PDF格式再上传 - case "btnChangeToUOT": //保存到UOT格式再上传 - case "btnChangeToOFD": //保存到OFD格式再上传 - case "SaveAll": //保存所有文档 - //以下四个idMso的控制是关于文档新建的 - case "FileNew": - case "FileNewMenu": - case "WindowNew": - case "FileNewBlankDocument": - return OnSetSaveToOAEnable(); - case "btnCloseRevision": - { - let bFlag = wps.PluginStorage.getItem(constStrEnum.RevisionEnableFlag) - return bFlag - } - case "btnOpenRevision": - { - let bFlag = wps.PluginStorage.getItem(constStrEnum.RevisionEnableFlag) - return !bFlag - } - case "PictureInsert": - return false; - case "TabInsert"://WPS自身tab:插入 - case "TabDeveloper": //WPS自身tab:开发工具 - // case "TabPageLayoutWord": //WPS自身tab:页面布局 - // case "TabReferences": //WPS自身tab:引用 - // case "TabReviewWord": //WPS自身tab:审阅 - // case "TabView": //WPS自身tab:视图 - { - if(pCheckIfOADoc()){ - return false;//如果是OA打开的文档,把这个几个tab不可用/隐藏 - }else{ - return true; - } - } - default: - ; - } - return true; -} \ No newline at end of file diff --git a/oaassist/WpsOAAssist/js/common/time.js b/oaassist/WpsOAAssist/js/common/time.js deleted file mode 100644 index 5981248..0000000 --- a/oaassist/WpsOAAssist/js/common/time.js +++ /dev/null @@ -1,157 +0,0 @@ -var MAX_DATE = 2958465 // about year 9999 -var MAX_DATE_1904 = 2957003 - -// Half a second, expressed in days -var HALF_SECOND = (1.0 / 172800.0) - -// Half a millisecond -var HALF_MILLISECOND = (1.0 / 2000.0) - -// 从 0000/1/1 到 1900/1/1 的时间序数值 -var SERIAL_BASE_NUM = 693959 - -// 从 0000/1/1 到 1904/1/1 的时间序数值 -var SERIAL_BASE_NUM_1904 = 695421 - -// 指示是否假定 1900 年为润年(兼容 Excel) -var YEAR1900_ISLEAP = 0 - -// One-based array of days in year at month start -var _afxMonthDays = - [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]; -var b1904 = false; -var bDisable1900Year = false; - -function toTime(dtSrc, b1904) { - var tmDest = {}; - var nDays = 0; // Number of days since Dec. 30, 1899 - var nDaysAbsolute = 0; // Number of days since 1/1/0 - var nSecsInDay = 0; // Time in seconds since midnight - var nMinutesInDay = 0; // Minutes in day - - var n400Years = 0; // Number of 400 year increments since 1/1/0 - var n400Century = 0; // Century within 400 year block (0,1,2 or 3) - var n4Years = 0; // Number of 4 year increments since 1/1/0 - var n4Day = 0; // Day within 4 year block - // (0 is 1/1/yr1, 1460 is 12/31/yr4) - var n4Yr = 0; // Year within 4 year block (0,1,2 or 3) - var bLeap4 = true; // true if 4 year block includes leap year - var bIs1900Year = false; // true if this year is 1900 - - var dblDate = dtSrc; // tempory serial date - - // Round to the second - if (0 == 0) - dblDate += ((dtSrc > 0.0) ? HALF_SECOND : -HALF_SECOND); - - // If a valid date, then this conversion should not overflow - nDays = Math.floor(dblDate); - - nDaysAbsolute = Math.floor(dblDate) + (b1904 ? SERIAL_BASE_NUM_1904 : SERIAL_BASE_NUM); // Add days from 1/1/0 to 12/30/1899 - - dblDate = Math.abs(dblDate); - var dblSecsInDay = (dblDate - Math.floor(dblDate)) * 86400.0; - - nSecsInDay = Math.floor(dblSecsInDay); - - // modified by tsingbo: - // Calculate the day of week (sun=0, mon=1...) - // -1 because 1/1/0 is Sat. - tmDest.tm_wday = Math.floor((nDaysAbsolute - 1) % 7); - - if (!bDisable1900Year && !b1904 && - nDaysAbsolute >= SERIAL_BASE_NUM && - nDaysAbsolute < SERIAL_BASE_NUM + 367) { - bIs1900Year = true; - n4Day = nDaysAbsolute - SERIAL_BASE_NUM; - bLeap4 = true; - n400Years = 4; - n400Century = 3; - n4Yr = 0; - } - else { - // Leap years every 4 yrs except centuries not multiples of 400. - n400Years = Math.floor(nDaysAbsolute / 146097); - - // Set nDaysAbsolute to day within 400-year block - nDaysAbsolute %= 146097; - - // -1 because first century has extra day - n400Century = Math.floor((nDaysAbsolute - 1) / 36524); - - // Non-leap century - if (n400Century != 0) { - // Set nDaysAbsolute to day within century - nDaysAbsolute = (nDaysAbsolute - 1) % 36524; - - // +1 because 1st 4 year increment has 1460 days - n4Years = Math.floor((nDaysAbsolute + 1) / 1461); - - if (n4Years != 0) - n4Day = Math.floor((nDaysAbsolute + 1) % 1461); - else { - bLeap4 = false; - n4Day = Math.floornDaysAbsolute; - } - } - else { - // Leap century - not special case! - n4Years = Math.floor(nDaysAbsolute / 1461); - n4Day = Math.floor(nDaysAbsolute % 1461); - } - - if (bLeap4) { - // -1 because first year has 366 days - n4Yr = (n4Day - 1) / 365; - - if (n4Yr != 0) - n4Day = (n4Day - 1) % 365; - } - else { - n4Yr = n4Day / 365; - n4Day %= 365; - } - } - - // n4Day is now 0-based day of year. Save 1-based day of year, year number - tmDest.tm_yday = Math.floor(n4Day) + 1; - tmDest.tm_year = Math.floor(n400Years * 400 + n400Century * 100 + n4Years * 4 + n4Yr); - - // Handle leap year: before, on, and after Feb. 29. - if (n4Yr == 0 && bLeap4) { - // Leap Year - if ((!bIs1900Year && n4Day == 59) || - (bIs1900Year && n4Day == 60)) { - /* Feb. 29 */ - tmDest.tm_mon = 2; - tmDest.tm_mday = 29; - } - else { - // Pretend it's not a leap year for month/day comp. - if (n4Day >= 60) - --n4Day; - } - } else { - // Make n4DaY a 1-based day of non-leap year and compute - // month/day for everything but Feb. 29. - if (!bIs1900Year) - ++n4Day; - - // Month number always >= n/32, so save some loop time */ - for (tmDest.tm_mon = (n4Day >> 5) + 1; - n4Day > _afxMonthDays[tmDest.tm_mon]; tmDest.tm_mon++); - - tmDest.tm_mday = Math.floor(n4Day - _afxMonthDays[tmDest.tm_mon - 1]); - } - - if (nSecsInDay == 0) - tmDest.tm_hour = tmDest.tm_min = tmDest.tm_sec = 0; - else { - tmDest.tm_sec = Math.floor(nSecsInDay % 60); - nMinutesInDay = nSecsInDay / 60; - tmDest.tm_min = Math.floor(nMinutesInDay % 60); - tmDest.tm_hour = Math.floor(nMinutesInDay / 60); - } - - return new Date(tmDest.tm_year, tmDest.tm_mon + 1, tmDest.tm_mday, tmDest.tm_mday, tmDest.tm_min, tmDest.tm_sec); -} diff --git a/oaassist/WpsOAAssist/js/main.js b/oaassist/WpsOAAssist/js/main.js deleted file mode 100644 index a079b09..0000000 --- a/oaassist/WpsOAAssist/js/main.js +++ /dev/null @@ -1,12 +0,0 @@ -//=======================依赖的第三方库======================= -var time=new Date().getTime() -document.write(""); -document.write(""); -//======================wps api常用枚举值===================== -document.write(""); -//=======================业务代码============================ -document.write(""); -document.write(""); -document.write(""); -document.write(""); -document.write(""); \ No newline at end of file diff --git a/oaassist/WpsOAAssist/otherslib/lib/formdata.js b/oaassist/WpsOAAssist/otherslib/lib/formdata.js deleted file mode 100644 index 1a3e9b5..0000000 --- a/oaassist/WpsOAAssist/otherslib/lib/formdata.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Emulate FormData for some browsers - * MIT License - * (c) 2010 François de Metz - */ -(function(w) { - if (w.FakeFormData) - return; - function FormData() { - this.fake = true; - this.boundary = "--------FormData" + Math.random(); - this._fields = []; - } - FormData.prototype.append = function(key, value) { - this._fields.push([key, value]); - } - FormData.prototype.toString = function() { - var boundary = this.boundary; - var body = ""; - this._fields.forEach(function(field) { - body += "--" + boundary + "\r\n"; - // file upload - if (field[1].name) { - var file = field[1]; - body += "Content-Disposition: form-data; name=\""+ field[0] +"\"; filename=\""+ file.name +"\"\r\n"; - body += "Content-Type: "+ file.type +"\r\n\r\n"; - body += file.getAsBinary() + "\r\n"; - } else { - body += "Content-Disposition: form-data; name=\""+ field[0] +"\";\r\n\r\n"; - body += field[1] + "\r\n"; - } - }); - body += "--" + boundary +"--"; - return body; - } - w.FakeFormData = FormData; -})(window); \ No newline at end of file diff --git a/oaassist/WpsOAAssist/otherslib/lib/jquery.min.js b/oaassist/WpsOAAssist/otherslib/lib/jquery.min.js deleted file mode 100644 index f4c12ca..0000000 --- a/oaassist/WpsOAAssist/otherslib/lib/jquery.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license -//@ sourceMappingURL=jquery-1.10.2.min.map -*/ -(function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,l=e.jQuery,u=e.$,c={},p=[],f="1.10.2",d=p.concat,h=p.push,g=p.slice,m=p.indexOf,y=c.toString,v=c.hasOwnProperty,b=f.trim,x=function(e,t){return new x.fn.init(e,t,r)},w=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=st(),k=st(),E=st(),S=!1,A=function(e,t){return e===t?(S=!0,0):0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=mt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+yt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,n,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function lt(e){return e[b]=!0,e}function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[r]]=t}function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function dt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.defaultView;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.attachEvent&&i!==i.top&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),r.getElementsByTagName=ut(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ut(function(e){return e.innerHTML="
",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ut(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=K.test(n.querySelectorAll))&&(ut(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="
a",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="
t
",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="
",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t -}({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,r=0,o=x(this),a=e.match(T)||[];while(t=a[r++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/\s*$/g,At={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X
","
"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?""!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle); -u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("" - // 默认切换到 wps - SwitchTab(0); - //demo三种模式进行切换 - envTest() //自动配置oem.ini - if(pluginsMode==1){ - installWpsAddin() //自动安装集成 - }else{ - //卸载掉publish模式 - curList=[] - installWpsAddin() - } - -} - -function IEVersion() { - var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 - var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器 - var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器 - var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1; - if (isIE) { - var reIE = new RegExp("MSIE (\\d+\\.\\d+);"); - reIE.test(userAgent); - var fIEVersion = parseFloat(RegExp["$1"]); - if (fIEVersion == 7) { - return 7; - } else if (fIEVersion == 8) { - return 8; - } else if (fIEVersion == 9) { - return 9; - } else if (fIEVersion == 10) { - return 10; - } else { - return 6; //IE版本<=7 - } - } else if (isEdge) { - return 20; //edge - } else if (isIE11) { - return 11; //IE11 - } else { - return 30; //不是ie浏览器 - } -} - -function getHttpObj() { - var httpobj = null; - if (IEVersion() < 10) { - try { - httpobj = new XDomainRequest(); - } catch (e1) { - httpobj = new createXHR(); - } - } else { - httpobj = new createXHR(); - } - return httpobj; -} -//兼容IE低版本的创建xmlhttprequest对象的方法 -function createXHR() { - if (typeof XMLHttpRequest != 'undefined') { //兼容高版本浏览器 - return new XMLHttpRequest(); - } else if (typeof ActiveXObject != 'undefined') { //IE6 采用 ActiveXObject, 兼容IE6 - var versions = [ //由于MSXML库有3个版本,因此都要考虑 - 'MSXML2.XMLHttp.6.0', - 'MSXML2.XMLHttp.3.0', - 'MSXML2.XMLHttp' - ]; - - for (var i = 0; i < versions.length; i++) { - try { - return new ActiveXObject(versions[i]); - } catch (e) { - //跳过 - } - } - } else { - throw new Error('您的浏览器不支持XHR对象'); - } -} \ No newline at end of file diff --git a/oaassist/server/wwwroot/resource/js/et.js b/oaassist/server/wwwroot/resource/js/et.js deleted file mode 100644 index f9e7842..0000000 --- a/oaassist/server/wwwroot/resource/js/et.js +++ /dev/null @@ -1,237 +0,0 @@ -var _et = {} - -var pluginsMode = location.search.split("=")[1];//截取url中的参数值 -var pluginType = WpsInvoke.ClientType.et//加载项类型wps,et,wpp -var pluginName = "EtOAAssist";//加载项名称 -var wpsClient = new WpsClient(pluginType);//初始化一个多进程对象,多进程时才需要 -var clientStr = pluginName + pluginType + "ClientId" -//单进程封装开始 -/** - * 此方法是根据wps_sdk.js做的调用方法封装 - * 可参照此定义 - * @param {*} funcs 这是在WPS加载项内部定义的方法,采用JSON格式(先方法名,再参数) - * @param {*} front 控制着通过页面执行WPS加载项方法,WPS的界面是否在执行时在前台显示 - * @param {*} jsPluginsXml 指定一个新的WPS加载项配置文件的地址,动态传递jsplugins.xml模式,例如:http://127.0.0.1:3888/jsplugins.xml - * @param {*} isSilent 隐藏打开WPS,如果需要隐藏,那么需要传递front参数为false - */ - - -function _WpsInvoke(funcs, front, jsPluginsXml,isSilent) { - var info = {}; - info.funcs = funcs; - if(isSilent){//隐藏启动时,front必须为false - front=false; - } - /** - * 下面函数为调起WPS,并且执行加载项WpsOAAssist中的函数dispatcher,该函数的参数为业务系统传递过去的info - */ - if (pluginsMode != 2) {//单进程 - singleInvoke(info,front,jsPluginsXml,isSilent) - } else {//多进程 - multInvoke(info,front,jsPluginsXml,isSilent) - } - -} - -//单进程 -function singleInvoke(info,front,jsPluginsXml,isSilent){ - WpsInvoke.InvokeAsHttp(pluginType, // 组件类型 - pluginName, // 插件名,与wps客户端加载的加载的插件名对应 - "dispatcher", // 插件方法入口,与wps客户端加载的加载的插件代码对应,详细见插件代码 - info, // 传递给插件的数据 - function (result) { // 调用回调,status为0为成功,其他是错误 - if (result.status) { - if (result.status == 100) { - WpsInvoke.AuthHttpesCert('请在稍后打开的网页中,点击"高级" => "继续前往",完成授权。') - return; - } - alert(result.message) - - } else { - console.log(result.response) - } - }, - front, - jsPluginsXml, - isSilent) - - /** - * 接受WPS加载项发送的消息 - * 接收消息:WpsInvoke.RegWebNotify(type,name,callback) - * WPS客户端返回消息: wps.OAAssist.WebNotify(message) - * @param {*} type 加载项对应的插件类型 - * @param {*} name 加载项对应的名字 - * @param {func} callback 接收到WPS客户端的消息后的回调函数,参数为接受到的数据 - */ - WpsInvoke.RegWebNotify(pluginType, pluginName, handleOaMessage) -} -//多进程 -function multInvoke(info,front,jsPluginsXml,isSilent){ - wpsClient.jsPluginsXml = jsPluginsXml ? jsPluginsXml : "https://127.0.0.1:3888/jsplugins.xml"; - if (localStorage.getItem(clientStr)) { - wpsClient.clientId = localStorage.getItem(clientStr) - } - if(isSilent){ - wpsClient.StartWpsInSilentMode(pluginName,function(){//隐藏启动后的回调函数 - mult(info,front) - }) - }else{ - mult(info,front) - } - wpsClient.onMessage = handleOaMessage -} -//多进程二次封装 -function mult(info,front){ - wpsClient.InvokeAsHttp( - pluginName, // 插件名,与wps客户端加载的加载的插件名对应 - "dispatcher", // 插件方法入口,与wps客户端加载的加载的插件代码对应,详细见插件代码 - info, // 传递给插件的数据         - function (result) { // 调用回调,status为0为成功,其他是错误 - if (wpsClient.clientId) { - localStorage.setItem(clientStr, wpsClient.clientId) - } - if (result.status !== 0) { - console.log(result) - if (result.message == '{\"data\": \"Failed to send message to WPS.\"}') { - wpsClient.IsClientRunning(function (status) { - console.log(status) - if (status.response == "Client is running.") - alert("任务发送失败,WPS 正在执行其他任务,请前往WPS完成当前任务") - else { - wpsClient.clientId = ""; - wpsClient.notifyRegsitered = false; - localStorage.setItem(clientStr, "") - mult(info) - } - }) - return; - } - else if (result.status == 100) { - // WpsInvoke.AuthHttpesCert('请在稍后打开的网页中,点击"高级" => "继续前往",完成授权。') - return; - } - alert(result.message) - } else { - console.log(result.response) - } - }, - front) -} - -function handleOaMessage(data) { - console.log(data) -} -function GetUploadPath() { - var url = document.location.host; - return document.location.protocol + "//" + url + "/Upload"; -} - -function GetDemoPath(fileName) { - - var url = document.location.host; - return document.location.protocol + "//" + url + "/file/" + fileName; -} - -function newDoc() { - _WpsInvoke([{ - "OpenDoc": { - showButton: "btnSaveFile;btnSaveAsLocal" - } - }]) -} - -_et['newDoc'] = { - action: newDoc, - code: _WpsInvoke.toString() + "\n\n" + newDoc.toString(), - detail: "\n\ - 说明:\n\ - 点击按钮,打开表格组件后,新建一个空白表格文档\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动表格组件,调用oaassist插件,执行插件中的js函数OpenDoc,不带文档路径则默认新建一个空白表格文档\n\ - funcs参数说明:\n\ - OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ - showButton 要显示的按钮\n\ -" -} - -function openDoc() { - var filePath = prompt("请输入打开文件路径(本地或是url):", GetDemoPath("样章.xlsx")) - var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()) - - _WpsInvoke([{ - "OpenDoc": { - "docId": "123", // 文档ID - "uploadPath": uploadPath, // 保存文档上传接口 - "fileName": filePath, - showButton: "btnSaveFile;btnSaveAsLocal" - } - }]) -} - -_et['openDoc'] = { - action: openDoc, - code: _WpsInvoke.toString() + "\n\n" + openDoc.toString(), - detail: "\n\ - 说明:\n\ - 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ - 打开表格组件后,将根据文档路径下载并打开对应的文档,保存将自动上传指定服务器地址\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动表格组件,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ - docId 文档ID,OA助手用以标记文档的信息,以区分其他文档\n\ - uploadPath 保存文档上传接口\n\ - fileName 打开的文档路径\n\ - showButton 要显示的按钮\n\ -" -} - -function onlineEditDoc() { - var filePath = prompt("请输入打开文件路径(本地或是url):", GetDemoPath("样章.xlsx")) - var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()) - - _WpsInvoke([{ - "OnlineEditDoc": { - "docId": "123", // 文档ID - "uploadPath": uploadPath, // 保存文档上传接口 - "fileName": filePath, - showButton: "btnSaveFile" - } - }]) -} - -_et['onlineEditDoc'] = { - action: onlineEditDoc, - code: _WpsInvoke.toString() + "\n\n" + onlineEditDoc.toString(), - detail: "\n\ - 说明:\n\ - 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ - 打开演示后,将根据文档路径下载并打开对应的文档,保存将自动上传指定服务器地址\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动演示组件,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OnlineEditDoc方法对应于OA助手dispatcher支持的方法名\n\ - docId 文档ID,OA助手用以标记文档的信息,以区分其他文档\n\ - uploadPath 保存文档上传接口\n\ - fileName 打开的文档路径\n\ - showButton 要显示的按钮\n\ -" -} - -window.onload = function () { - var btns = document.getElementsByClassName("btn"); - for (var i = 0; i < btns.length; i++) { - btns[i].onclick = function (event) { - document.getElementById("blockFunc").style.visibility = "visible"; - var btn2 = document.getElementById("demoBtn"); - btn2.innerText = this.innerText; - document.getElementById("codeDes").innerText = _et[this.id].detail.toString(); - document.getElementById("code").innerText = _et[this.id].code.toString(); - document.getElementById("demoBtn").onclick = _et[this.id].action; - hljs.highlightBlock(document.getElementById("code")); - } - } -} \ No newline at end of file diff --git a/oaassist/server/wwwroot/resource/js/utils/json2.js b/oaassist/server/wwwroot/resource/js/utils/json2.js deleted file mode 100644 index 7c00298..0000000 --- a/oaassist/server/wwwroot/resource/js/utils/json2.js +++ /dev/null @@ -1,433 +0,0 @@ -// json2.js -// 2017-06-12 -// Public Domain. -// NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -// USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO -// NOT CONTROL. -// This file creates a global JSON object containing two methods: stringify -// and parse. This file provides the ES5 JSON capability to ES3 systems. -// If a project might run on IE8 or earlier, then this file should be included. -// This file does nothing on ES5 systems. -// JSON.stringify(value, replacer, space) -// value any JavaScript value, usually an object or array. -// replacer an optional parameter that determines how object -// values are stringified for objects. It can be a -// function or an array of strings. -// space an optional parameter that specifies the indentation -// of nested structures. If it is omitted, the text will -// be packed without extra whitespace. If it is a number, -// it will specify the number of spaces to indent at each -// level. If it is a string (such as "\t" or " "), -// it contains the characters used to indent at each level. -// This method produces a JSON text from a JavaScript value. -// When an object value is found, if the object contains a toJSON -// method, its toJSON method will be called and the result will be -// stringified. A toJSON method does not serialize: it returns the -// value represented by the name/value pair that should be serialized, -// or undefined if nothing should be serialized. The toJSON method -// will be passed the key associated with the value, and this will be -// bound to the value. -// For example, this would serialize Dates as ISO strings. -// Date.prototype.toJSON = function (key) { -// function f(n) { -// // Format integers to have at least two digits. -// return (n < 10) -// ? "0" + n -// : n; -// } -// return this.getUTCFullYear() + "-" + -// f(this.getUTCMonth() + 1) + "-" + -// f(this.getUTCDate()) + "T" + -// f(this.getUTCHours()) + ":" + -// f(this.getUTCMinutes()) + ":" + -// f(this.getUTCSeconds()) + "Z"; -// }; -// You can provide an optional replacer method. It will be passed the -// key and value of each member, with this bound to the containing -// object. The value that is returned from your method will be -// serialized. If your method returns undefined, then the member will -// be excluded from the serialization. -// If the replacer parameter is an array of strings, then it will be -// used to select the members to be serialized. It filters the results -// such that only members with keys listed in the replacer array are -// stringified. -// Values that do not have JSON representations, such as undefined or -// functions, will not be serialized. Such values in objects will be -// dropped; in arrays they will be replaced with null. You can use -// a replacer function to replace those with JSON values. -// JSON.stringify(undefined) returns undefined. -// The optional space parameter produces a stringification of the -// value that is filled with line breaks and indentation to make it -// easier to read. -// If the space parameter is a non-empty string, then that string will -// be used for indentation. If the space parameter is a number, then -// the indentation will be that many spaces. -// Example: -// text = JSON.stringify(["e", {pluribus: "unum"}]); -// // text is '["e",{"pluribus":"unum"}]' -// text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t"); -// // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' -// text = JSON.stringify([new Date()], function (key, value) { -// return this[key] instanceof Date -// ? "Date(" + this[key] + ")" -// : value; -// }); -// // text is '["Date(---current time---)"]' -// JSON.parse(text, reviver) -// This method parses a JSON text to produce an object or array. -// It can throw a SyntaxError exception. -// The optional reviver parameter is a function that can filter and -// transform the results. It receives each of the keys and values, -// and its return value is used instead of the original value. -// If it returns what it received, then the structure is not modified. -// If it returns undefined then the member is deleted. -// Example: -// // Parse the text. Values that look like ISO date strings will -// // be converted to Date objects. -// myData = JSON.parse(text, function (key, value) { -// var a; -// if (typeof value === "string") { -// a = -// /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); -// if (a) { -// return new Date(Date.UTC( -// +a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6] -// )); -// } -// return value; -// } -// }); -// myData = JSON.parse( -// "[\"Date(09/09/2001)\"]", -// function (key, value) { -// var d; -// if ( -// typeof value === "string" -// && value.slice(0, 5) === "Date(" -// && value.slice(-1) === ")" -// ) { -// d = new Date(value.slice(5, -1)); -// if (d) { -// return d; -// } -// } -// return value; -// } -// ); -// This is a reference implementation. You are free to copy, modify, or -// redistribute. -/*jslint -eval, for, this -*/ -/*property -JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, -getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, -lastIndex, length, parse, prototype, push, replace, slice, stringify, -test, toJSON, toString, valueOf -*/ -// Create a JSON object only if one does not already exist. We create the -// methods in a closure to avoid creating global variables. -if (typeof JSON !== "object") { - JSON = {}; -} -(function () { - "use strict"; - var rx_one = /^[\],:{}\s]*$/; - var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g; - var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; - var rx_four = /(?:^|:|,)(?:\s*\[)+/g; - var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; - var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; - - function f(n) { - // Format integers to have at least two digits. - return (n < 10) ? - "0" + n : - n; - } - - function this_value() { - return this.valueOf(); - } - if (typeof Date.prototype.toJSON !== "function") { - Date.prototype.toJSON = function () { - return isFinite(this.valueOf()) ? - ( - this.getUTCFullYear() + - "-" + - f(this.getUTCMonth() + 1) + - "-" + - f(this.getUTCDate()) + - "T" + - f(this.getUTCHours()) + - ":" + - f(this.getUTCMinutes()) + - ":" + - f(this.getUTCSeconds()) + - "Z" - ) : - null; - }; - Boolean.prototype.toJSON = this_value; - Number.prototype.toJSON = this_value; - String.prototype.toJSON = this_value; - } - var gap; - var indent; - var meta; - var rep; - - function quote(string) { - // If the string contains no control characters, no quote characters, and no - // backslash characters, then we can safely slap some quotes around it. - // Otherwise we must also replace the offending characters with safe escape - // sequences. - rx_escapable.lastIndex = 0; - return rx_escapable.test(string) ? - "\"" + string.replace(rx_escapable, function (a) { - var c = meta[a]; - return typeof c === "string" ? - c : - "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4); - }) + "\"" : - "\"" + string + "\""; - } - - function str(key, holder) { - // Produce a string from holder[key]. - var i; // The loop counter. - var k; // The member key. - var v; // The member value. - var length; - var mind = gap; - var partial; - var value = holder[key]; - // If the value has a toJSON method, call it to obtain a replacement value. - if ( - value && - typeof value === "object" && - typeof value.toJSON === "function" - ) { - value = value.toJSON(key); - } - // If we were called with a replacer function, then call the replacer to - // obtain a replacement value. - if (typeof rep === "function") { - value = rep.call(holder, key, value); - } - // What happens next depends on the value's type. - switch (typeof value) { - case "string": - return quote(value); - case "number": - // JSON numbers must be finite. Encode non-finite numbers as null. - return (isFinite(value)) ? - String(value) : - "null"; - case "boolean": - case "null": - // If the value is a boolean or null, convert it to a string. Note: - // typeof null does not produce "null". The case is included here in - // the remote chance that this gets fixed someday. - return String(value); - // If the type is "object", we might be dealing with an object or an array or - // null. - case "object": - // Due to a specification blunder in ECMAScript, typeof null is "object", - // so watch out for that case. - if (!value) { - return "null"; - } - // Make an array to hold the partial results of stringifying this object value. - gap += indent; - partial = []; - // Is the value an array? - if (Object.prototype.toString.apply(value) === "[object Array]") { - // The value is an array. Stringify every element. Use null as a placeholder - // for non-JSON values. - length = value.length; - for (i = 0; i < length; i += 1) { - partial[i] = str(i, value) || "null"; - } - // Join all of the elements together, separated with commas, and wrap them in - // brackets. - v = partial.length === 0 ? - "[]" : - gap ? - ( - "[\n" + - gap + - partial.join(",\n" + gap) + - "\n" + - mind + - "]" - ) : - "[" + partial.join(",") + "]"; - gap = mind; - return v; - } - // If the replacer is an array, use it to select the members to be stringified. - if (rep && typeof rep === "object") { - length = rep.length; - for (i = 0; i < length; i += 1) { - if (typeof rep[i] === "string") { - k = rep[i]; - v = str(k, value); - if (v) { - partial.push(quote(k) + ( - (gap) ? - ": " : - ":" - ) + v); - } - } - } - } else { - // Otherwise, iterate through all of the keys in the object. - for (k in value) { - if (Object.prototype.hasOwnProperty.call(value, k)) { - v = str(k, value); - if (v) { - partial.push(quote(k) + ( - (gap) ? - ": " : - ":" - ) + v); - } - } - } - } - // Join all of the member texts together, separated with commas, - // and wrap them in braces. - v = partial.length === 0 ? - "{}" : - gap ? - "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}" : - "{" + partial.join(",") + "}"; - gap = mind; - return v; - } - } - // If the JSON object does not yet have a stringify method, give it one. - if (typeof JSON.stringify !== "function") { - meta = { // table of character substitutions - "\b": "\\b", - "\t": "\\t", - "\n": "\\n", - "\f": "\\f", - "\r": "\\r", - "\"": "\\\"", - "\\": "\\\\" - }; - JSON.stringify = function (value, replacer, space) { - // The stringify method takes a value and an optional replacer, and an optional - // space parameter, and returns a JSON text. The replacer can be a function - // that can replace values, or an array of strings that will select the keys. - // A default replacer method can be provided. Use of the space parameter can - // produce text that is more easily readable. - var i; - gap = ""; - indent = ""; - // If the space parameter is a number, make an indent string containing that - // many spaces. - if (typeof space === "number") { - for (i = 0; i < space; i += 1) { - indent += " "; - } - // If the space parameter is a string, it will be used as the indent string. - } else if (typeof space === "string") { - indent = space; - } - // If there is a replacer, it must be a function or an array. - // Otherwise, throw an error. - rep = replacer; - if (replacer && typeof replacer !== "function" && ( - typeof replacer !== "object" || - typeof replacer.length !== "number" - )) { - throw new Error("JSON.stringify"); - } - // Make a fake root object containing our value under the key of "". - // Return the result of stringifying the value. - return str("", { - "": value - }); - }; - } - // If the JSON object does not yet have a parse method, give it one. - if (typeof JSON.parse !== "function") { - JSON.parse = function (text, reviver) { - // The parse method takes a text and an optional reviver function, and returns - // a JavaScript value if the text is a valid JSON text. - var j; - - function walk(holder, key) { - // The walk method is used to recursively walk the resulting structure so - // that modifications can be made. - var k; - var v; - var value = holder[key]; - if (value && typeof value === "object") { - for (k in value) { - if (Object.prototype.hasOwnProperty.call(value, k)) { - v = walk(value, k); - if (v !== undefined) { - value[k] = v; - } else { - delete value[k]; - } - } - } - } - return reviver.call(holder, key, value); - } - // Parsing happens in four stages. In the first stage, we replace certain - // Unicode characters with escape sequences. JavaScript handles many characters - // incorrectly, either silently deleting them, or treating them as line endings. - text = String(text); - rx_dangerous.lastIndex = 0; - if (rx_dangerous.test(text)) { - text = text.replace(rx_dangerous, function (a) { - return ( - "\\u" + - ("0000" + a.charCodeAt(0).toString(16)).slice(-4) - ); - }); - } - // In the second stage, we run the text against regular expressions that look - // for non-JSON patterns. We are especially concerned with "()" and "new" - // because they can cause invocation, and "=" because it can cause mutation. - // But just to be safe, we want to reject all unexpected forms. - // We split the second stage into 4 regexp operations in order to work around - // crippling inefficiencies in IE's and Safari's regexp engines. First we - // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we - // replace all simple value tokens with "]" characters. Third, we delete all - // open brackets that follow a colon or comma or that begin the text. Finally, - // we look to see that the remaining characters are only whitespace or "]" or - // "," or ":" or "{" or "}". If that is so, then the text is safe for eval. - if ( - rx_one.test( - text - .replace(rx_two, "@") - .replace(rx_three, "]") - .replace(rx_four, "") - ) - ) { - // In the third stage we use the eval function to compile the text into a - // JavaScript structure. The "{" operator is subject to a syntactic ambiguity - // in JavaScript: it can begin a block or an object literal. We wrap the text - // in parens to eliminate the ambiguity. - j = eval("(" + text + ")"); - // In the optional fourth stage, we recursively walk the new structure, passing - // each name/value pair to a reviver function for possible transformation. - return (typeof reviver === "function") ? - walk({ - "": j - }, "") : - j; - } - // If the text is not JSON parseable, then a SyntaxError is thrown. - throw new SyntaxError("JSON.parse"); - }; - } -}()); \ No newline at end of file diff --git a/oaassist/server/wwwroot/resource/js/wpp.js b/oaassist/server/wwwroot/resource/js/wpp.js deleted file mode 100644 index c818825..0000000 --- a/oaassist/server/wwwroot/resource/js/wpp.js +++ /dev/null @@ -1,238 +0,0 @@ -var _wpp = {} - -var pluginsMode = location.search.split("=")[1];//截取url中的参数值 -var pluginType = WpsInvoke.ClientType.wpp//加载项类型wps,et,wpp -var pluginName = "WppOAAssist";//加载项名称 -var wpsClient = new WpsClient(pluginType);//初始化一个多进程对象,多进程时才需要 -var clientStr = pluginName + pluginType + "ClientId" -//单进程封装开始 -/** - * 此方法是根据wps_sdk.js做的调用方法封装 - * 可参照此定义 - * @param {*} funcs 这是在WPS加载项内部定义的方法,采用JSON格式(先方法名,再参数) - * @param {*} front 控制着通过页面执行WPS加载项方法,WPS的界面是否在执行时在前台显示 - * @param {*} jsPluginsXml 指定一个新的WPS加载项配置文件的地址,动态传递jsplugins.xml模式,例如:http://127.0.0.1:3888/jsplugins.xml - * @param {*} isSilent 隐藏打开WPS,如果需要隐藏,那么需要传递front参数为false - */ - - -function _WpsInvoke(funcs, front, jsPluginsXml,isSilent) { - var info = {}; - info.funcs = funcs; - if(isSilent){//隐藏启动时,front必须为false - front=false; - } - /** - * 下面函数为调起WPS,并且执行加载项WpsOAAssist中的函数dispatcher,该函数的参数为业务系统传递过去的info - */ - if (pluginsMode != 2) {//单进程 - singleInvoke(info,front,jsPluginsXml,isSilent) - } else {//多进程 - multInvoke(info,front,jsPluginsXml,isSilent) - } - -} - -//单进程 -function singleInvoke(info,front,jsPluginsXml,isSilent){ - WpsInvoke.InvokeAsHttp(pluginType, // 组件类型 - pluginName, // 插件名,与wps客户端加载的加载的插件名对应 - "dispatcher", // 插件方法入口,与wps客户端加载的加载的插件代码对应,详细见插件代码 - info, // 传递给插件的数据 - function (result) { // 调用回调,status为0为成功,其他是错误 - if (result.status) { - if (result.status == 100) { - WpsInvoke.AuthHttpesCert('请在稍后打开的网页中,点击"高级" => "继续前往",完成授权。') - return; - } - alert(result.message) - - } else { - console.log(result.response) - } - }, - front, - jsPluginsXml, - isSilent) - - /** - * 接受WPS加载项发送的消息 - * 接收消息:WpsInvoke.RegWebNotify(type,name,callback) - * WPS客户端返回消息: wps.OAAssist.WebNotify(message) - * @param {*} type 加载项对应的插件类型 - * @param {*} name 加载项对应的名字 - * @param {func} callback 接收到WPS客户端的消息后的回调函数,参数为接受到的数据 - */ - WpsInvoke.RegWebNotify(pluginType, pluginName, handleOaMessage) -} -//多进程 -function multInvoke(info,front,jsPluginsXml,isSilent){ - wpsClient.jsPluginsXml = jsPluginsXml ? jsPluginsXml : "https://127.0.0.1:3888/jsplugins.xml"; - if (localStorage.getItem(clientStr)) { - wpsClient.clientId = localStorage.getItem(clientStr) - } - if(isSilent){ - wpsClient.StartWpsInSilentMode(pluginName,function(){//隐藏启动后的回调函数 - mult(info,front) - }) - }else{ - mult(info,front) - } - wpsClient.onMessage = handleOaMessage -} -//多进程二次封装 -function mult(info,front){ - wpsClient.InvokeAsHttp( - pluginName, // 插件名,与wps客户端加载的加载的插件名对应 - "dispatcher", // 插件方法入口,与wps客户端加载的加载的插件代码对应,详细见插件代码 - info, // 传递给插件的数据         - function (result) { // 调用回调,status为0为成功,其他是错误 - if (wpsClient.clientId) { - localStorage.setItem(clientStr, wpsClient.clientId) - } - if (result.status !== 0) { - console.log(result) - if (result.message == '{\"data\": \"Failed to send message to WPS.\"}') { - wpsClient.IsClientRunning(function (status) { - console.log(status) - if (status.response == "Client is running.") - alert("任务发送失败,WPS 正在执行其他任务,请前往WPS完成当前任务") - else { - wpsClient.clientId = ""; - wpsClient.notifyRegsitered = false; - localStorage.setItem(clientStr, "") - mult(info) - } - }) - return; - } - else if (result.status == 100) { - // WpsInvoke.AuthHttpesCert('请在稍后打开的网页中,点击"高级" => "继续前往",完成授权。') - return; - } - alert(result.message) - } else { - console.log(result.response) - } - }, - front) -} -function handleOaMessage(data) { - console.log(data) -} -function GetDemoPath(fileName) { - - var url = document.location.host; - return document.location.protocol + "//" + url + "/file/" + fileName; -} - -function GetUploadPath() { - var url = document.location.host; - return document.location.protocol + "//" + url + "/Upload"; -} - -function newDoc() { - _WpsInvoke([{ - "OpenDoc": { - showButton: "btnSaveFile;btnSaveAsLocal" - } - }]) -} - -_wpp['newDoc'] = { - action: newDoc, - code: _WpsInvoke.toString() + "\n\n" + newDoc.toString(), - detail: "\n\ - 说明:\n\ - 点击按钮,打开演示组件后,新建一个空白演示文档\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动演示组件,调用oaassist插件,执行插件中的js函数OpenDoc,不带文档路径则默认新建一个空白演示文档\n\ - funcs参数说明:\n\ - OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ - showButton 要显示的按钮\n\ -" -} - -function openDoc() { - var filePath = prompt("请输入打开文件路径(本地或是url):", GetDemoPath("样章.pptx")) - var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()) - - _WpsInvoke([{ - "OpenDoc": { - "docId": "123", // 文档ID - "uploadPath": uploadPath, // 保存文档上传接口 - "fileName": filePath, - showButton: "btnSaveFile;btnSaveAsLocal" - } - }]) -} - -_wpp['openDoc'] = { - action: openDoc, - code: _WpsInvoke.toString() + "\n\n" + openDoc.toString(), - detail: "\n\ - 说明:\n\ - 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ - 打开演示后,将根据文档路径下载并打开对应的文档,保存将自动上传指定服务器地址\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动演示组件,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ - docId 文档ID,OA助手用以标记文档的信息,以区分其他文档\n\ - uploadPath 保存文档上传接口\n\ - fileName 打开的文档路径\n\ - showButton 要显示的按钮\n\ -" -} - -function onlineEditDoc() { - var filePath = prompt("请输入打开文件路径(本地或是url):", GetDemoPath("样章.pptx")) - var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()) - - _WpsInvoke([{ - "OnlineEditDoc": { - "docId": "123", // 文档ID - "uploadPath": uploadPath, // 保存文档上传接口 - "fileName": filePath, - showButton: "btnSaveFile;btnSaveAsLocal" - } - }]) -} - -_wpp['onlineEditDoc'] = { - action: onlineEditDoc, - code: _WpsInvoke.toString() + "\n\n" + onlineEditDoc.toString(), - detail: "\n\ - 说明:\n\ - 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ - 打开演示后,将根据文档路径下载并打开对应的文档,保存将自动上传指定服务器地址\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动演示组件,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OnlineEditDoc方法对应于OA助手dispatcher支持的方法名\n\ - docId 文档ID,OA助手用以标记文档的信息,以区分其他文档\n\ - uploadPath 保存文档上传接口\n\ - fileName 打开的文档路径\n\ - showButton 要显示的按钮\n\ -" -} - -window.onload = function () { - var btns = document.getElementsByClassName("btn"); - - for (var i = 0; i < btns.length; i++) { - btns[i].onclick = function (event) { - document.getElementById("blockFunc").style.visibility = "visible"; - var btn2 = document.getElementById("demoBtn"); - btn2.innerText = this.innerText; - document.getElementById("codeDes").innerText = _wpp[this.id].detail.toString() - document.getElementById("code").innerText = _wpp[this.id].code.toString() - document.getElementById("demoBtn").onclick = _wpp[this.id].action; - - hljs.highlightBlock(document.getElementById("code")); - } - } -} \ No newline at end of file diff --git a/oaassist/server/wwwroot/resource/js/wps.js b/oaassist/server/wwwroot/resource/js/wps.js deleted file mode 100644 index 5a047b2..0000000 --- a/oaassist/server/wwwroot/resource/js/wps.js +++ /dev/null @@ -1,924 +0,0 @@ -var pluginsMode = location.search.split("=")[1]; //截取url中的参数值 -var pluginType = WpsInvoke.ClientType.wps; //加载项类型wps,et,wpp -var pluginName = "WpsOAAssist"; //加载项名称 -var wpsClient = new WpsClient(pluginType); //初始化一个多进程对象,多进程时才需要 -var clientStr = pluginName + pluginType + "ClientId"; -//单进程封装开始 -/** - * 此方法是根据wps_sdk.js做的调用方法封装 - * 可参照此定义 - * @param {*} funcs 这是在WPS加载项内部定义的方法,采用JSON格式(先方法名,再参数) - * @param {*} front 控制着通过页面执行WPS加载项方法,WPS的界面是否在执行时在前台显示 - * @param {*} jsPluginsXml 指定一个新的WPS加载项配置文件的地址,动态传递jsplugins.xml模式,例如:http://127.0.0.1:3888/jsplugins.xml - * @param {*} isSilent 隐藏打开WPS,如果需要隐藏,那么需要传递front参数为false - */ - -function _WpsInvoke(funcs, front, jsPluginsXml, isSilent) { - var info = {}; - info.funcs = funcs; - if (isSilent) { - //隐藏启动时,front必须为false - front = false; - } - /** - * 下面函数为调起WPS,并且执行加载项WpsOAAssist中的函数dispatcher,该函数的参数为业务系统传递过去的info - */ - if (pluginsMode != 2) { - //单进程 - singleInvoke(info, front, jsPluginsXml, isSilent); - } else { - //多进程 - multInvoke(info, front, jsPluginsXml, isSilent); - } -} - -//单进程 -function singleInvoke(info, front, jsPluginsXml, isSilent) { - WpsInvoke.InvokeAsHttp( - pluginType, // 组件类型 - pluginName, // 插件名,与wps客户端加载的加载的插件名对应 - "dispatcher", // 插件方法入口,与wps客户端加载的加载的插件代码对应,详细见插件代码 - info, // 传递给插件的数据 - function (result) { - // 调用回调,status为0为成功,其他是错误 - if (result.status) { - if (result.status == 100) { - WpsInvoke.AuthHttpesCert( - '请在稍后打开的网页中,点击"高级" => "继续前往",完成授权。' - ); - return; - } - alert(result.message); - } else { - console.log(result.response); - showresult(result.response); - } - }, - front, - jsPluginsXml, - isSilent - ); - - /** - * 接受WPS加载项发送的消息 - * 接收消息:WpsInvoke.RegWebNotify(type,name,callback) - * WPS客户端返回消息: wps.OAAssist.WebNotify(message) - * @param {*} type 加载项对应的插件类型 - * @param {*} name 加载项对应的名字 - * @param {func} callback 接收到WPS客户端的消息后的回调函数,参数为接受到的数据 - */ - WpsInvoke.RegWebNotify(pluginType, pluginName, handleOaMessage); -} -//多进程 -function multInvoke(info, front, jsPluginsXml, isSilent) { - wpsClient.jsPluginsXml = jsPluginsXml - ? jsPluginsXml - : "https://127.0.0.1:3888/jsplugins.xml"; - if (localStorage.getItem(clientStr)) { - wpsClient.clientId = localStorage.getItem(clientStr); - } - if (isSilent) { - wpsClient.StartWpsInSilentMode(pluginName, function () { - //隐藏启动后的回调函数 - mult(info, front); - }); - } else { - mult(info, front); - } - wpsClient.onMessage = handleOaMessage; -} -//多进程二次封装 -function mult(info, front) { - wpsClient.InvokeAsHttp( - pluginName, // 插件名,与wps客户端加载的加载的插件名对应 - "dispatcher", // 插件方法入口,与wps客户端加载的加载的插件代码对应,详细见插件代码 - info, // 传递给插件的数据 - function (result) { - // 调用回调,status为0为成功,其他是错误 - if (wpsClient.clientId) { - localStorage.setItem(clientStr, wpsClient.clientId); - } - if (result.status !== 0) { - console.log(result); - if (result.message == '{"data": "Failed to send message to WPS."}') { - wpsClient.IsClientRunning(function (status) { - console.log(status); - if (status.response == "Client is running.") - alert( - "任务发送失败,WPS 正在执行其他任务,请前往WPS完成当前任务" - ); - else { - wpsClient.clientId = ""; - wpsClient.notifyRegsitered = false; - localStorage.setItem(clientStr, ""); - mult(info); - } - }); - return; - } else if (result.status == 100) { - // WpsInvoke.AuthHttpesCert('请在稍后打开的网页中,点击"高级" => "继续前往",完成授权。') - return; - } - alert(result.message); - } else { - console.log(result.response); - } - }, - front - ); -} -function handleOaMessage(data) { - console.log(data); -} - -function handleOaFunc1(message) { - alert("我是函数handleOaFunc1,我接收到的参数是:" + message); -} -function handleOaFunc2(message) { - alert("我是函数handleOaFunc2,我接收到的参数是:" + message); - var span = window.parent.document.getElementById("webnotifyspan"); - span.innerHTML = message; -} -/** - * 处理WPS加载项的方法返回值 - * - * @param {*} resultData - */ -function showresult(resultData) { - let json = eval("(" + resultData + ")"); - switch (json.message) { - case "GetDocStatus": { - let docstatus = json.docstatus; - if (typeof docstatus != "undefined") { - let str = - "文档保存状态:" + - docstatus.saved + - "\n文档字数:" + - docstatus.words + - "\n文档页数:" + - docstatus.pages; - alert(str); - } - } - } -} -/** - * 这是页面中针对代码显示的变量定义,开发者无需关心 - */ -var _wps = {}; - -// 此处往下,都是对于前端页面如何调用WPS加载项方法的样例,开发者请参考 - -function newDoc() { - console.log("sasaa"); - _WpsInvoke( - [ - { - NewDoc: {}, - }, - ], - true, - "http://127.0.0.1:8080/iestart/jsplugins.xml" - ); // NewDoc方法对应于OA助手dispatcher支持的方法名 -} - -_wps["newDoc"] = { - action: newDoc, - code: _WpsInvoke.toString() + "\n\n" + newDoc.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,打开WPS文字后,新建一个空白doc文档\n\ -\n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行插件中的js函数NewDoc,新建一个空白doc\n\ - funcs参数说明:\n\ - NewDoc方法对应于OA助手dispatcher支持的方法名\n\ -", -}; - -function GetDemoPath(fileName) { - var url = document.location.host; - return document.location.protocol + "//" + url + "/file/" + fileName; -} - -function GetUploadPath() { - var url = document.location.host; - return document.location.protocol + "//" + url + "/Upload"; -} - -function GetDemoPngPath() { - var url = document.location.toString(); - url = decodeURI(url); - if (url.indexOf("/") != -1) { - url = url.substring(0, url.lastIndexOf("/")); - } - if (url.length !== 0) url = url.concat("/WPS.png"); - - if (!String.prototype.startsWith) { - String.prototype.startsWith = function (searchString, position) { - position = position || 0; - return this.indexOf(searchString, position) === position; - }; - } - - if (url.startsWith("file:///")) url = url.substr("file:///".length); - return url; -} - -function openDoc() { - var filePath = prompt( - "请输入打开文件路径(本地或是url):", - GetDemoPath("样章.docx") - ); - var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()); - var uploadFieldName = prompt( - "请输入文档上传到业务系统时自定义字段:", - "自定义字段" - ); - var backupPath = prompt("请输入文档备份路径:"); - - _WpsInvoke([ - { - OpenDoc: { - uploadPath: uploadPath, // 保存文档上传接口 - fileName: filePath, - uploadFieldName: uploadFieldName, - picPath: GetDemoPngPath(), - copyUrl: backupPath, - userName: "东方不败", - }, - }, - ]); // OpenDoc方法对应于OA助手dispatcher支持的方法名 -} - -_wps["openDoc"] = { - action: openDoc, - code: _WpsInvoke.toString() + "\n\n" + openDoc.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ - 打开WPS文字后,将根据文档路径下载并打开对应的文档,保存将自动上传指定服务器地址\n\ -\n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ - uploadPath 保存文档上传接口\n\ - fileName 打开的文档路径\n\ - uploadFieldName 文档上传到业务系统时自定义字段\n\ - picPath 插入图片的路径\n\ - copyUrl 备份的服务器路径\n\ - userName 传给wps要显示的OA用户名\n\ -", -}; - -function onlineEditDoc() { - var filePath = prompt( - "请输入打开文件路径(本地或是url):", - GetDemoPath("样章.docx") - ); - var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()); - var uploadFieldName = prompt( - "请输入文档上传到业务系统时自定义字段:", - "自定义字段" - ); - _WpsInvoke( - [ - { - OnlineEditDoc: { - uploadPath: uploadPath, // 保存文档上传接口 - fileName: filePath, - uploadFieldName: uploadFieldName, - buttonGroups: - "btnSaveAsFile,btnImportDoc,btnPageSetup,btnInsertDate,btnSelectBookmark", //屏蔽功能按钮 - userName: "东方不败", - }, - }, - ], - true - ); // onlineEditDoc方法对应于OA助手dispatcher支持的方法名 -} - -_wps["onlineEditDoc"] = { - action: onlineEditDoc, - code: _WpsInvoke.toString() + "\n\n" + onlineEditDoc.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ - 打开WPS文字后,将根据文档路径在线打开对应的文档,保存将自动上传指定服务器地址\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - onlineEditDoc方法对应于OA助手dispatcher支持的方法名\n\ - uploadPath 保存文档上传接口\n\ - fileName 打开的文档路径\n\ - uploadFieldName 文档上传到业务系统时自定义字段\n\ - buttonGroups 屏蔽的OA助手功能按钮\n\ - userName 传给wps要显示的OA用户名\n\ -", -}; - -function openRevision() { - var filePath = prompt( - "请输入打开文件路径(本地或是url):", - GetDemoPath("样章.docx") - ); - var uploadPath = prompt("请输入文档上传接口:"); - _WpsInvoke([ - { - OpenDoc: { - uploadPath: uploadPath, // 保存文档上传接口 - fileName: filePath, - userName: "王五", //用户名 - revisionCtrl: { - bOpenRevision: true, - bShowRevision: true, - }, - }, - }, - ]); -} - -_wps["openRevision"] = { - action: openRevision, - code: _WpsInvoke.toString() + "\n\n" + openRevision.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,输入参数后,打开WPS文字后,打开指定文档,并打开修订功能,并显示修订\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ - userName 用户名,设置当前编辑用户名\n\ - fileName 打开的文档路径\n\ - revisionCtrl 修订功能控制参数\n\ -", -}; - -function closeRevision() { - var filePath = prompt( - "请输入打开文件路径(本地或是url):", - GetDemoPath("样章.docx") - ); - var uploadPath = prompt("请输入文档上传接口:"); - _WpsInvoke([ - { - OpenDoc: { - uploadPath: uploadPath, // 保存文档上传接口 - fileName: filePath, - userName: "王五", //用户名 - revisionCtrl: { - bOpenRevision: false, - bShowRevision: false, - }, - }, - }, - ]); -} - -_wps["closeRevision"] = { - action: closeRevision, - code: _WpsInvoke.toString() + "\n\n" + closeRevision.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,输入参数后,打开WPS文字后,打开指定文档,并关闭修订功能\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ - userName 用户名,设置当前编辑用户名\n\ - fileName 打开的文档路径\n\ - revisionCtrl 修订功能控制参数\n\ -", -}; - -function protectOpen() { - var filePath = prompt( - "请输入打开文件路径(本地或是url):", - GetDemoPath("样章.docx") - ); - var uploadPath = prompt("请输入文档上传接口:"); - _WpsInvoke([ - { - OpenDoc: { - uploadPath: uploadPath, // 保存文档上传接口 - fileName: filePath, - openType: { - //文档打开方式 - // 文档保护类型,-1:不启用保护模式,0:只允许对现有内容进行修订, - // 1:只允许添加批注,2:只允许修改窗体域(禁止拷贝功能),3:只读 - protectType: 3, - password: "123456", - }, - }, - }, - ]); -} - -_wps["protectOpen"] = { - action: protectOpen, - code: _WpsInvoke.toString() + "\n\n" + protectOpen.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,输入参数后,打开WPS文字后,打开使用保护模式指定文档\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ - uploadPath 保存文档上传接口\n\ - fileName 打开的文档路径\n\ - openType 文档打开方式控制参数 protectType:1:不启用保护模式,0:只允许对现有内容进行修订,\n\ - \t\t1:只允许添加批注,2:只允许修改窗体域(禁止拷贝功能),3:只读 password为密码\n\ -", -}; - -function openWithPassWd() { - var filePath = prompt("请输入打开文件路径(本地或是url):"); - var docPassword = prompt("请输入文档打开密码:"); - var uploadPath = prompt("请输入文档上传接口:"); - _WpsInvoke([ - { - OpenDoc: { - uploadPath: uploadPath, // 保存文档上传接口 - fileName: filePath, - docPassword: { - docPassword: docPassword, // 文档密码 - }, - }, - }, - ]); -} - -_wps["openWithPassWd"] = { - action: openWithPassWd, - code: _WpsInvoke.toString() + "\n\n" + openWithPassWd.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,输入参数后,打开WPS文字后,使用指定密码打开指定加密文档\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ - uploadPath 保存文档上传接口\n\ - fileName 打开的文档路径\n\ - docPassword 文档密码\n\ -", -}; - -function insertRedHeader() { - var filePath = prompt( - "请输入打开文件路径,如果为空则对活动文档套红:", - GetDemoPath("样章.docx") - ); - var templateURL = prompt( - "请输入红头模板路径(本地或是url):", - GetDemoPath("红头文件.docx") - ); - if (filePath != "" && filePath != null) { - _WpsInvoke([ - { - OnlineEditDoc: { - fileName: filePath, - insertFileUrl: templateURL, - bkInsertFile: "Content", //红头模板中填充正文的位置书签名 - buttonGroups: - "btnSaveAsFile,btnImportDoc,btnPageSetup,btnInsertDate,btnSelectBookmark", //屏蔽功能按钮 - }, - }, - ]); - } else { - _WpsInvoke([ - { - InsertRedHead: { - insertFileUrl: templateURL, - bkInsertFile: "Content", //红头模板中填充正文的位置书签名 - }, - }, - ]); - } -} - -_wps["insertRedHeader"] = { - action: insertRedHeader, - code: _WpsInvoke.toString() + "\n\n" + insertRedHeader.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,输入参数后,打开WPS文字后,打开指定文档,然后使用指定红头模板对该文档进行套红头\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ - fileName 打开的文档路径\n\ - insertFileUrl 指定的红头模板\n\ - bkInsertFile 红头模板中正文的位置书签名\n\ - InsertRedHead方法对应于OA助手dispatcher支持的方法名\n\ - insertFileUrl 指定的红头模板\n\ - bkInsertFile 红头模板中正文的位置书签名\n\ -", -}; - -function fillTemplate() { - var filePath = prompt( - "请输入打开文件路径(本地或是url):", - GetDemoPath("样章2.docx") - ); - var templatePath = prompt( - "请输入需要填充的数据的请求地址:", - document.location.protocol + - "//" + - document.location.host + - "/getTemplateData" - ); - - _WpsInvoke([ - { - OpenDoc: { - fileName: filePath, - templateDataUrl: templatePath, - }, - }, - ]); // OpenDoc方法对应于OA助手dispatcher支持的方法名 -} - -_wps["fillTemplate"] = { - action: fillTemplate, - code: _WpsInvoke.toString() + "\n\n" + fillTemplate.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,输入要打开的文档路径,输入文档上传接口,打开WPS文字后,将根据文档路径下载并打开对应的文档,\n\ - 并自动从模板服务器获取模板数据并套用到文档中\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ - fileName 打开的文档路径\n\ - templateDataUrl 模板的服务器路径\n\ -", -}; - -function convertDoc() { - var filePath = prompt( - "请输入打开文件路径(本地或是url):", - GetDemoPath("样章.docx") - ); - var uploadPath = prompt("请输入文档转换后上传接口:", GetUploadPath()); - - _WpsInvoke([ - { - OpenDoc: { - uploadPath: uploadPath, // 保存文档上传接口 - fileName: filePath, - suffix: ".pdf", - uploadWithAppendPath: "1", //与suffix配置使用,传入标志位即可 - }, - }, - ]); // OpenDoc方法对应于OA助手dispatcher支持的方法名 -} - -_wps["convertDoc"] = { - action: convertDoc, - code: _WpsInvoke.toString() + "\n\n" + convertDoc.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,输入要打开的文档路径,输入文档转换后上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ - 打开WPS文字后,将根据文档路径下载并打开对应的文档,转换完将自动上传指定服务器地址\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ - uploadPath 保存文档上传接口\n\ - fileName 打开的文档路径\n\ - suffix 转换类型\n\ - uploadWithAppendPath 保存时一并转换的目标格式\n\ -", -}; - -function taskPaneBookMark() { - var filePath = prompt( - "请输入打开带书签文件路径(本地或是url):", - GetDemoPath("样章.docx") - ); - _WpsInvoke([ - { - taskPaneBookMark: { - fileName: filePath, - userName: "东方不败", - }, - }, - ]); // taskPaneBookMark方法对应于OA助手dispatcher支持的方法名 -} - -_wps["taskPaneBookMark"] = { - action: taskPaneBookMark, - code: _WpsInvoke.toString() + "\n\n" + taskPaneBookMark.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,输入要打开的文档路径,文档中的书签将会在OA助手的Taskpane中显示出来。\n\ - 点击TaskPane中的书签,会自动跳转到书签所对应的文件中的位置,点击Taskpane按F2键可以看Taskpane中的html源码。\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - taskPaneBookMark 方法对应于OA助手dispatcher支持的方法名\n\ - fileName 文档的路径\n\ - userName 传给wps要显示的OA用户名\n\ -", -}; - -function exitWPS() { - _WpsInvoke( - [ - { - ExitWPS: {}, - }, - ], - true - ); -} - -_wps["exitWPS"] = { - action: exitWPS, - code: _WpsInvoke.toString() + "\n\n" + exitWPS.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,关闭已打开的WPS\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议通知WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - ExitWPS 方法对应于OA助手dispatcher支持的方法名\n\ -", -}; - -function getDocStatus() { - _WpsInvoke( - [ - { - GetDocStatus: {}, - }, - ], - false - ); -} - -_wps["getDocStatus"] = { - action: getDocStatus, - code: _WpsInvoke.toString() + "\n\n" + getDocStatus.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,获取活动文档的状态\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议通知WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - GetDocStatus 方法对应于OA助手dispatcher支持的方法名\n\ -", -}; - -//----公文写作的相关方法 这些都必须是在有「公文写作」组件的版本中运行 Start-------- -/** - * 判断当前OS是否是Linux系统 - * - * @returns - */ -function checkOSisLinux() { - if (detectOS() == "Linux") { - return true; - } else { - alert("此方法仅在WPS Linux特定版本支持"); - } -} -/** - * 新建一个使用公文写作打开的公文 - * - */ -function newOfficialDocument() { - if (checkOSisLinux()) { - _WpsInvoke([ - { - NewOfficialDocument: { - isOfficialDocument: true, - }, - }, - ]); // NewOfficialDocument方法对应于OA助手dispatcher支持的方法名 - } -} - -_wps["newOfficialDocument"] = { - action: newOfficialDocument, - code: _WpsInvoke.toString() + "\n\n" + newOfficialDocument.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,打开WPS公文写作后,新建一个公文\n\ -\n\ - 方法使用:\n\ - 页面点击按钮, 通过wps客户端协议来启动WPS, 调用oaassist插件, 执行插件中的js函数NewOfficialDocument, 新建一个默认模板的公文 n\ - funcs参数说明:\n\ - NewOfficialDocument方法对应于OA助手dispatcher支持的方法名 n\ -", -}; - -/** - * 打开一个使用公文写作打开的公文 - */ -function openOfficialDocument() { - if (checkOSisLinux()) { - var filePath = prompt( - "请输入打开文件路径(本地或是url):", - GetDemoPath("公文样章.wps") - ); - var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()); - var uploadFieldName = prompt( - "请输入文档上传到业务系统时自定义字段:", - "自定义字段" - ); - var backupPath = prompt("请输入文档备份路径:"); - _WpsInvoke([ - { - OpenDoc: { - uploadPath: uploadPath, // 保存文档上传接口 - fileName: filePath, - uploadFieldName: uploadFieldName, - picPath: GetDemoPngPath(), - copyUrl: backupPath, - userName: "东方不败", - }, - }, - ]); // OpenDoc方法对应于OA助手dispatcher支持的方法名 - } -} -_wps["openOfficialDocument"] = { - action: openOfficialDocument, - code: _WpsInvoke.toString() + "\n\n" + openOfficialDocument.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ - 打开WPS文字后,将根据文档路径下载并打开对应的文档,保存将自动上传指定服务器地址\n\ -\n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ - uploadPath 保存文档上传接口\n\ - fileName 打开的文档路径\n\ - uploadFieldName 文档上传到业务系统时自定义字段\n\ - picPath 插入图片的路径\n\ - copyUrl 备份的服务器路径\n\ - userName 传给wps要显示的OA用户名\n\ -", -}; -/** - * 在线不落地打开一个使用公文写作打开的公文 - */ -function onlineEditOfficialDocument() { - if (checkOSisLinux()) { - var filePath = prompt( - "请输入打开文件路径(本地或是url):", - GetDemoPath("公文样章.wps") - ); - var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()); - var uploadFieldName = prompt( - "请输入文档上传到业务系统时自定义字段:", - "自定义字段" - ); - _WpsInvoke([ - { - OnlineEditDoc: { - uploadPath: uploadPath, // 保存文档上传接口 - fileName: filePath, - uploadFieldName: uploadFieldName, - buttonGroups: - "btnSaveAsFile,btnImportDoc,btnPageSetup,btnInsertDate,btnSelectBookmark", //屏蔽功能按钮 - userName: "东方不败", - }, - }, - ]); // onlineEditDoc方法对应于OA助手dispatcher支持的方法名 - } -} - -_wps["onlineEditOfficialDocument"] = { - action: onlineEditOfficialDocument, - code: _WpsInvoke.toString() + "\n\n" + onlineEditOfficialDocument.toString(), - detail: - "\n\ - 说明:\n\ - 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ - 打开WPS文字后,将根据文档路径在线打开对应的文档,保存将自动上传指定服务器地址\n\ - \n\ - 方法使用:\n\ - 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ - funcs参数信息说明:\n\ - OnlineEditDoc方法对应于OA助手dispatcher支持的方法名\n\ - uploadPath 保存文档上传接口\n\ - fileName 打开的文档路径\n\ - uploadFieldName 文档上传到业务系统时自定义字段\n\ - buttonGroups 屏蔽的OA助手功能按钮\n\ - userName 传给wps要显示的OA用户名\n\ -", -}; - -/** - * 这是HTML页面上的按钮赋予事件的实现,开发者无需关心,使用自己习惯的方式做开发即可 - */ -window.onload = function () { - var btns = document.getElementsByClassName("btn"); - - for (var i = 0; i < btns.length; i++) { - btns[i].onclick = function (event) { - document.getElementById("blockFunc").style.visibility = "visible"; - var btn2 = document.getElementById("demoBtn"); - btn2.innerText = this.innerText; - document.getElementById("codeDes").innerText = - _wps[this.id].detail.toString(); - document.getElementById("code").innerText = _wps[this.id].code.toString(); - var onBtnAction = _wps[this.id].action; - - // document.getElementById("demoBtn").onclick = onBtnAction //IE不支持箭头函数,改为通用写法 - document.getElementById("demoBtn").onclick = function () { - //IE不支持箭头函数,改为通用写法 - //之下动作是做了对Node服务的判断和oem.ini的设置 - var xhr = new WpsInvoke.CreateXHR(); - xhr.onload = function () { - onBtnAction(); - }; - xhr.onerror = function () { - alert("请确认本地服务端(StartupServer.js)是启动状态"); - return; - }; - xhr.open("get", "http://127.0.0.1:3888/FileList", true); - xhr.send(); - }; - - hljs.highlightBlock(document.getElementById("code")); - }; - } -}; -/** - * 检查操作系统 - * - * @returns Win10 | Win7 | WinVista | Win2003 | WinXP | Win2000 | Linux | Unix | Mac - */ -function detectOS() { - var sUserAgent = navigator.userAgent; - var isWin = navigator.platform == "Win32" || navigator.platform == "Windows"; - var isMac = - navigator.platform == "Mac68K" || - navigator.platform == "MacPPC" || - navigator.platform == "Macintosh" || - navigator.platform == "MacIntel"; - if (isMac) return "Mac"; - var isUnix = navigator.platform == "X11" && !isWin && !isMac; - if (isUnix) return "Unix"; - var isLinux = String(navigator.platform).indexOf("Linux") > -1; - if (isLinux) return "Linux"; - if (isWin) { - var isWin2K = - sUserAgent.indexOf("Windows NT 5.0") > -1 || - sUserAgent.indexOf("Windows 2000") > -1; - if (isWin2K) return "Win2000"; - var isWinXP = - sUserAgent.indexOf("Windows NT 5.1") > -1 || - sUserAgent.indexOf("Windows XP") > -1; - if (isWinXP) return "WinXP"; - var isWin2003 = - sUserAgent.indexOf("Windows NT 5.2") > -1 || - sUserAgent.indexOf("Windows 2003") > -1; - if (isWin2003) return "Win2003"; - var isWinVista = - sUserAgent.indexOf("Windows NT 6.0") > -1 || - sUserAgent.indexOf("Windows Vista") > -1; - if (isWinVista) return "WinVista"; - var isWin7 = - sUserAgent.indexOf("Windows NT 6.1") > -1 || - sUserAgent.indexOf("Windows 7") > -1; - if (isWin7) return "Win7"; - var isWin10 = - sUserAgent.indexOf("Windows NT 6.1") > -1 || - sUserAgent.indexOf("Windows 10") > -1; - if (isWin10) return "Win10"; - } - return "other"; -} diff --git a/oaassist/server/wwwroot/resource/js/wps_sdk.js b/oaassist/server/wwwroot/resource/js/wps_sdk.js deleted file mode 100644 index ec9ca6e..0000000 --- a/oaassist/server/wwwroot/resource/js/wps_sdk.js +++ /dev/null @@ -1,957 +0,0 @@ -(function (global, factory) { - - "use strict"; - - if (typeof module === "object" && typeof module.exports === "object") { - module.exports = factory(global, true); - } else { - factory(global); - } - -})(typeof window !== "undefined" ? window : this, function (window, noGlobal) { - - "use strict"; - - var bFinished = true; - - function getHttpObj() { - var httpobj = null; - if (IEVersion() < 10) { - try { - httpobj = new XDomainRequest(); - } catch (e1) { - httpobj = new createXHR(); - } - } else { - httpobj = new createXHR(); - } - return httpobj; - } - //兼容IE低版本的创建xmlhttprequest对象的方法 - function createXHR() { - if (typeof XMLHttpRequest != 'undefined') { //兼容高版本浏览器 - return new XMLHttpRequest(); - } else if (typeof ActiveXObject != 'undefined') { //IE6 采用 ActiveXObject, 兼容IE6 - var versions = [ //由于MSXML库有3个版本,因此都要考虑 - 'MSXML2.XMLHttp.6.0', - 'MSXML2.XMLHttp.3.0', - 'MSXML2.XMLHttp' - ]; - - for (var i = 0; i < versions.length; i++) { - try { - return new ActiveXObject(versions[i]); - } catch (e) { - //跳过 - } - } - } else { - throw new Error('您的浏览器不支持XHR对象'); - } - } - - function startWps(options) { - if (!bFinished && !options.concurrent) { - if (options.callback) - options.callback({ - status: 1, - message: "上一次请求没有完成" - }); - return; - } - bFinished = false; - - function startWpsInnder(tryCount) { - if (tryCount <= 0) { - if (bFinished) - return; - bFinished = true; - if (options.callback) - options.callback({ - status: 2, - message: "请允许浏览器打开WPS Office" - }); - return; - } - var xmlReq = getHttpObj(); - //WPS客户端提供的接收参数的本地服务,HTTP服务端口为58890,HTTPS服务端口为58891 - //这俩配置,取一即可,不可同时启用 - xmlReq.open('POST', options.url); - xmlReq.onload = function (res) { - bFinished = true; - if (options.callback) { - options.callback({ - status: 0, - response: IEVersion() < 10 ? xmlReq.responseText : res.target.response - }); - } - } - xmlReq.ontimeout = xmlReq.onerror = function (res) { - xmlReq.bTimeout = true; - if (tryCount == options.tryCount && options.bPop) { //打开wps并传参 - window.location.href = "ksoWPSCloudSvr://start=RelayHttpServer" //是否启动wps弹框 - } - setTimeout(function () { - startWpsInnder(tryCount - 1) - }, 1000); - } - if (IEVersion() < 10) { - xmlReq.onreadystatechange = function () { - if (xmlReq.readyState != 4) - return; - if (xmlReq.bTimeout) { - return; - } - if (xmlReq.status === 200) - xmlReq.onload(); - else - xmlReq.onerror(); - } - } - xmlReq.timeout = options.timeout; - xmlReq.send(options.sendData) - } - startWpsInnder(options.tryCount); - return; - } - - var fromCharCode = String.fromCharCode; - // encoder stuff - var cb_utob = function (c) { - if (c.length < 2) { - var cc = c.charCodeAt(0); - return cc < 0x80 ? c : - cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6)) + - fromCharCode(0x80 | (cc & 0x3f))) : - (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f)) + - fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + - fromCharCode(0x80 | (cc & 0x3f))); - } else { - var cc = 0x10000 + - (c.charCodeAt(0) - 0xD800) * 0x400 + - (c.charCodeAt(1) - 0xDC00); - return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07)) + - fromCharCode(0x80 | ((cc >>> 12) & 0x3f)) + - fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + - fromCharCode(0x80 | (cc & 0x3f))); - } - }; - var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; - var utob = function (u) { - return u.replace(re_utob, cb_utob); - }; - var _encode = function (u) { - var isUint8Array = Object.prototype.toString.call(u) === '[object Uint8Array]'; - if (isUint8Array) - return u.toString('base64') - else - return btoa(utob(String(u))); - } - - if (typeof window.btoa !== 'function') window.btoa = func_btoa; - - function func_btoa(input) { - var str = String(input); - var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - for ( - // initialize result and counter - var block, charCode, idx = 0, map = chars, output = ''; - // if the next str index does not exist: - // change the mapping table to "=" - // check if d has no fractional digits - str.charAt(idx | 0) || (map = '=', idx % 1); - // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 - output += map.charAt(63 & block >> 8 - idx % 1 * 8) - ) { - charCode = str.charCodeAt(idx += 3 / 4); - if (charCode > 0xFF) { - throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); - } - block = block << 8 | charCode; - } - return output; - } - - var encode = function (u, urisafe) { - return !urisafe ? - _encode(u) : - _encode(String(u)).replace(/[+\/]/g, function (m0) { - return m0 == '+' ? '-' : '_'; - }).replace(/=/g, ''); - }; - - function IEVersion() { - var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 - var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器 - var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器 - var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1; - if (isIE) { - var reIE = new RegExp("MSIE (\\d+\\.\\d+);"); - reIE.test(userAgent); - var fIEVersion = parseFloat(RegExp["$1"]); - if (fIEVersion == 7) { - return 7; - } else if (fIEVersion == 8) { - return 8; - } else if (fIEVersion == 9) { - return 9; - } else if (fIEVersion == 10) { - return 10; - } else { - return 6; //IE版本<=7 - } - } else if (isEdge) { - return 20; //edge - } else if (isIE11) { - return 11; //IE11 - } else { - return 30; //不是ie浏览器 - } - } - - function WpsStart(options) { - var startInfo = { - "name": options.name, - "function": options.func, - "info": options.param.param, - "jsPluginsXml": options.param.jsPluginsXml - }; - var strData = JSON.stringify(startInfo); - if (IEVersion() < 10) { - try { - eval("strData = '" + JSON.stringify(startInfo) + "';"); - } catch (err) { - - } - } - - var baseData = encode(strData); - var url = options.urlBase + "/" + options.clientType + "/runParams"; - var data = "ksowebstartup" + options.clientType + "://" + baseData; - startWps({ - url: url, - sendData: data, - callback: options.callback, - tryCount: options.tryCount, - bPop: options.bPop, - timeout: 5000, - concurrent: false, - client: options.wpsclient - }); - } - - function WpsStartWrap(options) { - WpsStart({ - clientType: options.clientType, - name: options.name, - func: options.func, - param: options.param, - urlBase: options.urlBase, - callback: options.callback, - tryCount: 4, - bPop: true, - wpsclient: options.wpsclient, - }) - } - - /** - * 支持浏览器触发,WPS有返回值的启动 - * - * @param {*} clientType 组件类型 - * @param {*} name WPS加载项名称 - * @param {*} func WPS加载项入口方法 - * @param {*} param 参数:包括WPS加载项内部定义的方法,参数等 - * @param {*} callback 回调函数 - * @param {*} tryCount 重试次数 - * @param {*} bPop 是否弹出浏览器提示对话框 - */ - var exId = 0; - function WpsStartWrapExInner(options) { - var infocontent = options.param.param; - if (!options.wpsclient) { - infocontent = JSON.stringify(options.param.param); - var rspUrl = options.urlBase + "/transferEcho/runParams"; - var time = new Date(); - var cmdId = "js" + time.getTime() + "_" + exId; - var funcEx = "var res = " + options.func; - var cbCode = "var xhr = new XMLHttpRequest();xhr.open('POST', '" + rspUrl + "');xhr.send(JSON.stringify({id: '" + cmdId + "', response: res}));" //res 为func执行返回值 - var infoEx = infocontent + ");" + cbCode + "void(0"; - options.func = funcEx; - infocontent = infoEx; - } - var startInfo = { - "name": options.name, - "function": options.func, - "info": infocontent, - "showToFront": options.param.showToFront, - "jsPluginsXml": options.param.jsPluginsXml, - }; - - var strData = JSON.stringify(startInfo); - if (IEVersion() < 10) { - try { - eval("strData = '" + JSON.stringify(startInfo) + "';"); - } catch (err) { - - } - } - - var baseData = encode(strData); - var wrapper; - - if (!options.wpsclient) { - var url = options.urlBase + "/transfer/runParams"; - var data = "ksowebstartup" + options.clientType + "://" + baseData; - wrapper = { - id: cmdId, - app: options.clientType, - data: data - }; - } - else { - var url = options.urlBase + "/transferEx/runParams"; - wrapper = { - id: options.wpsclient.clientId, - app: options.clientType, - data: baseData, - mode: options.wpsclient.silentMode ? "true" : "false" - }; - } - wrapper = JSON.stringify(wrapper); - startWps({ - url: url, - sendData: wrapper, - callback: options.callback, - tryCount: options.tryCount, - bPop: options.bPop, - timeout: 0, - concurrent: options.concurrent, - client: options.wpsclient - }); - } - - var serverVersion = "wait" - var cloudSvrStart = true; - function WpsStartWrapVersionInner(options) { - if (serverVersion == "wait") { - if (cloudSvrStart == false) { - window.location.href = "ksoWPSCloudSvr://start=RelayHttpServer" //是否启动wps弹框 - } - startWps({ - url: options.urlBase + '/version', - data: "", - callback: function (res) { - if (res.status !== 0) { - options.callback(res) - return; - } - serverVersion = res.response; - cloudSvrStart = true; - options.tryCount = 1 - options.bPop = false - if (serverVersion === "") { - WpsStart(options) - } else if (serverVersion < "1.0.1" && options.wpsclient) { - if (options.callback) { - options.callback({ - status: 4, - message: "当前客户端不支持,请升级客户端" - }) - } - } else { - WpsStartWrapExInner(options); - } - }, - tryCount: 4, - bPop: true, - timeout: 5000, - concurrent: options.concurrent - }); - } else { - if (serverVersion === "") { - WpsStartWrap(options) - } else if (serverVersion < "1.0.1" && options.wpsclient) { - if (options.callback) { - options.callback({ - status: 4, - message: "当前客户端不支持,请升级客户端" - }) - } - } else { - WpsStartWrapExInner(options); - } - } - } - - var RegWebNotifyMap = { wps: {}, wpp: {}, et: {} } - var bWebNotifyUseTimeout = true - function WebNotifyUseTimeout(value) { - bWebNotifyUseTimeout = value ? true : false - } - /** - * 注册一个前端页面接收WPS传来消息的方法 - * @param {*} clientType wps | et | wpp - * @param {*} name WPS加载项的名称 - * @param {*} callback 回调函数 - */ - function RegWebNotify(clientType, name, callback, wpsclient) { - if (clientType != "wps" && clientType != "wpp" && clientType != "et") - return; - var paramStr = {} - if (wpsclient) { - if (wpsclient.notifyRegsitered == true) { - return - } - wpsclient.notifyRegsitered = true; - paramStr = { - clientId: wpsclient.clientId, - name: name, - type: clientType - } - } - else { - if (typeof callback != 'function') - return - if (RegWebNotifyMap[clientType][name]) { - RegWebNotifyMap[clientType][name] = callback; - return - } - var RegWebNotifyID = new Date().valueOf() + '' - paramStr = { - id: RegWebNotifyID, - name: name, - type: clientType - } - RegWebNotifyMap[clientType][name] = callback - } - - var askItem = function () { - var xhr = getHttpObj() - xhr.onload = function (e) { - if (xhr.responseText == "WPSInnerMessage_quit") { - return; - } - if (wpsclient) { - wpsclient.OnRegWebNotify(xhr.responseText) - } else { - var func = RegWebNotifyMap[clientType][name] - func(xhr.responseText) - } - window.setTimeout(askItem, 300) - } - xhr.onerror = function (e) { - if (bWebNotifyUseTimeout) - window.setTimeout(askItem, 1000) - else - window.setTimeout(askItem, 10000) - } - xhr.ontimeout = function (e) { - if (bWebNotifyUseTimeout) - window.setTimeout(askItem, 300) - else - window.setTimeout(askItem, 10000) - } - if (IEVersion() < 10) { - xhr.onreadystatechange = function () { - if (xhr.readyState != 4) - return; - if (xhr.bTimeout) { - return; - } - if (xhr.status === 200) - xhr.onload(); - else - xhr.onerror(); - } - } - xhr.open('POST', GetUrlBase() + '/askwebnotify', true) - if (bWebNotifyUseTimeout) - xhr.timeout = 2000; - xhr.send(JSON.stringify(paramStr)) - } - - window.setTimeout(askItem, 2000) - } - - function GetUrlBase() { - if (location.protocol == "http:") - return "http://127.0.0.1:58890" - return "https://127.0.0.1:58891" - } - - function WpsStartWrapVersion(clientType, name, func, param, callback, showToFront, jsPluginsXml) { - var paramEx = { - jsPluginsXml: jsPluginsXml ? jsPluginsXml : "", - showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, - param: (typeof (param) == 'object' ? param : JSON.parse(param)) - } - var options = { - clientType: clientType, - name: name, - func: func, - param: paramEx, - urlBase: GetUrlBase(), - callback: callback, - wpsclient: undefined, - concurrent: true - } - WpsStartWrapVersionInner(options); - } - - //从外部浏览器远程调用 WPS 加载项中的方法 - var WpsInvoke = { - InvokeAsHttp: WpsStartWrapVersion, - InvokeAsHttps: WpsStartWrapVersion, - RegWebNotify: RegWebNotify, - ClientType: { - wps: "wps", - et: "et", - wpp: "wpp" - }, - CreateXHR: getHttpObj, - IsClientRunning: IsClientRunning - } - - window.wpsclients = []; - /** - * @constructor WpsClient wps客户端 - * @param {string} clientType 必传参数,加载项类型,有效值为"wps","wpp","et";分别表示文字,演示,电子表格 - */ - function WpsClient(clientType) { - /** - * 设置RegWebNotify的回调函数,加载项给业务端发消息通过该函数 - * @memberof WpsClient - * @member onMessage - */ - this.onMessage; - - /** - * 设置加载项路径 - * @memberof WpsClient - * @member jsPluginsXml - */ - this.jsPluginsXml; - - /** - * 内部成员,外部无需调用 - */ - this.notifyRegsitered = false; - this.clientId = ""; - this.concurrent = false; - this.clientType = clientType; - this.firstRequest = true; - - /** - * 内部函数,外部无需调用 - * @param {*} options - */ - this.initWpsClient = function (options) { - options.clientType = this.clientType - options.wpsclient = this - options.concurrent = this.firstRequest ? true : this.concurrent - this.firstRequest = false; - WpsStartWrapVersionInner(options) - } - - /** - * 以http启动 - * @param {string} name 加载项名称 - * @param {string} func 要调用的加载项中的函数行 - * @param {string} param 在加载项中执行函数func要传递的数据 - * @param {function({int, string})} callback 回调函数,status = 0 表示成功,失败请查看message信息 - * @param {bool} showToFront 设置wps是否显示到前面来 - * @return {string} "Failed to send message to WPS." 发送消息失败,客户端已关闭; - * "WPS Addon is not response." 加载项阻塞,函数执行失败 - */ - this.InvokeAsHttp = function (name, func, param, callback, showToFront) { - function clientCallback(res) { - //this不是WpsClient - if (res.status !== 0 || serverVersion < "1.0.1") { - if (callback) callback(res); - return; - } - var resObject = JSON.parse(res.response); - if (this.client.clientId == "") { - this.client.clientId = resObject.clientId; - } - this.client.concurrent = true; - if (typeof resObject.data == "object") - res.response = JSON.stringify(resObject.data); - else - res.response = resObject.data; - if (IEVersion() < 10) - eval(" res.response = '" + res.response + "';"); - if (callback) - callback(res); - this.client.RegWebNotify(name); - } - var paramEx = { - jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "", - showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, - param: (typeof (param) == 'object' ? param : JSON.parse(param)) - } - this.initWpsClient({ - name: name, - func: func, - param: paramEx, - urlBase: GetUrlBase(), - callback: clientCallback - }) - } - - /** - * 以https启动 - * @param {string} name 加载项名称 - * @param {string} func 要调用的加载项中的函数行 - * @param {string} param 在加载项中执行函数func要传递的数据 - * @param {function({int, string})} callback 回调函数,status = 0 表示成功,失败请查看message信息 - * @param {bool} showToFront 设置wps是否显示到前面来 - */ - this.InvokeAsHttps = function (name, func, param, callback, showToFront) { - var paramEx = { - jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "", - showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, - param: (typeof (param) == 'object' ? param : JSON.parse(param)) - } - this.initWpsClient({ - name: name, - func: func, - param: paramEx, - urlBase: GetUrlBase(), - callback: callback - }) - } - - /** - * 内部函数,外部无需调用 - * @param {*} name - */ - this.RegWebNotify = function (name) { - RegWebNotify(this.clientType, name, null, this); - } - - this.OnRegWebNotify = function (message) { - if (this.onMessage) - this.onMessage(message) - } - - /** - * 以静默模式启动客户端 - * @param {string} name 必传参数,加载项名称 - * @param {function({int, string})} [callback] 回调函数,status = 0 表示成功,失败请查看message信息 - */ - this.StartWpsInSilentMode = function (name, callback) { - function initCallback(res) { - //this不是WpsClient - if (res.status !== 0 || serverVersion < "1.0.1") { - if (callback) callback(res); - return; - } - if (this.client.clientId == "") { - this.client.clientId = JSON.parse(res.response).clientId; - window.wpsclients[window.wpsclients.length] = { name: name, client: this.client }; - } - res.response = JSON.stringify(JSON.parse(res.response).data); - this.client.concurrent = true; - if (callback) { - callback(res); - } - this.client.RegWebNotify(name); - } - var paramEx = { - jsPluginsXml: this.jsPluginsXml, - showToFront: false, - param: { status: "InitInSilentMode" } - } - this.silentMode = true; - this.initWpsClient({ - name: name, - func: "", - param: paramEx, - urlBase: GetUrlBase(), - callback: initCallback - }) - } - - /** - * 显示客户端到最前面 - * @param {string} name 必传参数,加载项名称 - * @param {function({int, string})} [callback] 回调函数 - */ - this.ShowToFront = function (name, callback) { - if (serverVersion < "1.0.1") { - if (callback) { - callback({ - status: 4, - message: "当前客户端不支持,请升级客户端" - }); - return; - } - return; - } - if (this.clientId == "") { - if (callback) callback({ - status: 3, - message: "没有静默启动客户端" - }); - return; - } - var paramEx = { - jsPluginsXml: "", - showToFront: true, - param: { status: "ShowToFront" } - } - this.initWpsClient({ - name: name, - func: "", - param: paramEx, - urlBase: GetUrlBase(), - callback: callback - }) - } - - /** - * 关闭未显示出来的静默启动客户端 - * @param {string} name 必传参数,加载项名称 - * @param {function({int, string})} [callback] 回调函数 - */ - this.CloseSilentClient = function (name, callback) { - if (serverVersion < "1.0.1") { - if (callback) { - callback({ - status: 4, - message: "当前客户端不支持,请升级客户端" - }); - return; - } - return; - } - if (this.clientId == "") { - if (callback) callback({ - status: 3, - message: "没有静默启动客户端" - }); - return; - } - var paramEx = { - jsPluginsXml: "", - showToFront: false, - param: undefined - } - var func; - if (this.clientType == "wps") - func = "wps.WpsApplication().Quit" - else if (this.clientType == "et") - func = "wps.EtApplication().Quit" - else if (this.clientType == "wpp") - func = "wps.WppApplication().Quit" - - function closeSilentClient(res) { - if (res.status == 0) - this.client.clientId = "" - if (callback) callback(res); - return; - } - this.initWpsClient({ - name: name, - func: func, - param: paramEx, - urlBase: GetUrlBase(), - callback: closeSilentClient - }) - } - - /** - * 当前客户端是否在运行,使用WpsClient.IsClientRunning()进行调用 - * @param {function({int, string})} [callback] 回调函数,"Client is running." 客户端正在运行 - * "Client is not running." 客户端没有运行 - */ - this.IsClientRunning = function (callback) { - if (serverVersion < "1.0.1") { - if (callback) { - callback({ - status: 4, - message: "当前客户端不支持,请升级客户端" - }); - return; - } - return; - } - IsClientRunning(this.clientType, callback, this) - } - } - - function InitSdk() { - var url = GetUrlBase() + "/version"; - startWps({ - url: url, - data: "", - callback: function (res) { - if (res.status !== 0) { - cloudSvrStart = false; - return; - } - if (serverVersion == "wait") { - serverVersion = res.response; - cloudSvrStart = true; - } - }, - tryCount: 1, - bPop: false, - timeout: 5000 - }); - } - - if (typeof noGlobal === "undefined") { - window.WpsInvoke = WpsInvoke; - window.WpsClient = WpsClient; - window.WebNotifyUseTimeout = WebNotifyUseTimeout; - InitSdk(); - } - - /** - * 当前客户端是否在运行,使用WpsInvoke.IsClientRunning()进行调用 - * @param {string} clientType 加载项类型 - * @param {function} [callback] 回调函数,"Client is running." 客户端正在运行 - * "Client is not running." 客户端没有运行 - */ - function IsClientRunning(clientType, callback, wpsclient) { - var url = GetUrlBase() + "/isRunning"; - var wrapper = { - id: wpsclient == undefined ? undefined : wpsclient.clientId, - app: clientType - } - wrapper = JSON.stringify(wrapper); - startWps({ - url: url, - sendData: wrapper, - callback: callback, - tryCount: 1, - bPop: false, - timeout: 2000, - concurrent: true, - client: wpsclient - }); - } - - function WpsAddonGetAllConfig(callBack) { - var baseData; - startWps({ - url: GetUrlBase() + "/publishlist", - type: "GET", - sendData: baseData, - callback: callBack, - tryCount: 3, - bPop: true, - timeout: 5000, - concurrent: true - }); - } - - function WpsAddonVerifyStatus(element, callBack) { - var xmlReq = getHttpObj(); - var offline = element.online === "false"; - var url = offline ? element.url : element.url + "ribbon.xml"; - xmlReq.open("POST", GetUrlBase() + "/redirect/runParams"); - xmlReq.onload = function (res) { - if (offline && !res.target.response.startsWith("7z")) { - callBack({ status: 1, msg: "不是有效的7z格式" + url }); - } else if (!offline && !res.target.response.startsWith(">> 6)) + - fromCharCode(0x80 | (cc & 0x3f))) : - (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f)) + - fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + - fromCharCode(0x80 | (cc & 0x3f))); - } else { - var cc = 0x10000 + - (c.charCodeAt(0) - 0xD800) * 0x400 + - (c.charCodeAt(1) - 0xDC00); - return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07)) + - fromCharCode(0x80 | ((cc >>> 12) & 0x3f)) + - fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + - fromCharCode(0x80 | (cc & 0x3f))); - } - }; - var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; - var utob = function (u) { - return u.replace(re_utob, cb_utob); - }; - var _encode = function (u) { - var isUint8Array = Object.prototype.toString.call(u) === '[object Uint8Array]'; - if (isUint8Array) - return u.toString('base64') - else - return btoa(utob(String(u))); - } - - if (typeof window.btoa !== 'function') window.btoa = func_btoa; - - function func_btoa(input) { - var str = String(input); - var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - for ( - // initialize result and counter - var block, charCode, idx = 0, map = chars, output = ''; - // if the next str index does not exist: - // change the mapping table to "=" - // check if d has no fractional digits - str.charAt(idx | 0) || (map = '=', idx % 1); - // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 - output += map.charAt(63 & block >> 8 - idx % 1 * 8) - ) { - charCode = str.charCodeAt(idx += 3 / 4); - if (charCode > 0xFF) { - throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); - } - block = block << 8 | charCode; - } - return output; - } - - /** - * 将字符串进行Base64编码 - * @param {*} u 需要编码的数据 - * @param {*} urisafe 返回值,编码后的数据 - * @returns urisafe - */ - var encode = function (u, urisafe) { - return !urisafe ? - _encode(u) : - _encode(String(u)).replace(/[+\/]/g, function (m0) { - return m0 == '+' ? '-' : '_'; - }).replace(/=/g, ''); - }; - - /** - * 获取IE浏览器版本 - * @returns IE浏览器版本 - */ - function IEVersion() { - var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 - var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器 - var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器 - var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1; - if (isIE) { - var reIE = new RegExp("MSIE (\\d+\\.\\d+);"); - reIE.test(userAgent); - var fIEVersion = parseFloat(RegExp["$1"]); - if (fIEVersion == 7) { - return 7; - } else if (fIEVersion == 8) { - return 8; - } else if (fIEVersion == 9) { - return 9; - } else if (fIEVersion == 10) { - return 10; - } else { - return 6; //IE版本<=7 - } - } else if (isEdge) { - return 20; //edge - } else if (isIE11) { - return 11; //IE11 - } else { - return 30; //不是ie浏览器 - } - } - - /** - * 启动wps客户端,加载项执行操作,无返回值 - * @param {*} options 参数对象,详情见下: - * @param {*} clientType 加载项类型, wps / wpp / et - * @param {*} name 加载项名称 - * @param {*} func 客户端加载项要执行的方法 - * @param {*} param 客户端家乡执行方法的参数 - * @param {*} urlBase 网页路径前缀 - * @param {*} callback 回调函数 - * @param {*} tryCount 请求失败后的尝试次数 - * @param {*} bPop 是否弹出浏览器提示对话框 - * @param {*} wpsclient wpsclient对象 - */ - function WpsStart(options) { - var startInfo = { - "name": options.name, - "function": options.func, - "info": options.param.param, - "jsPluginsXml": options.param.jsPluginsXml - }; - var strData = JSON.stringify(startInfo); - if (IEVersion() < 10) { - try { - eval("strData = '" + JSON.stringify(startInfo) + "';"); - } catch (err) { - - } - } - - var baseData = encode(strData); - var url = options.urlBase + "/" + options.clientType + "/runParams"; - var data = "ksowebstartup" + options.clientType + "://" + baseData; - startWps({ - url: url, - sendData: data, - callback: options.callback, - tryCount: options.tryCount, - bPop: options.bPop, - timeout: 5000, - concurrent: false, - client: options.wpsclient - }); - } - - /** - * 服务端版本为空时,通过该接口启动wps - * @param {*} options 参数对象,详情见下: - * @param {*} clientType 加载项类型, wps / wpp / et - * @param {*} name 加载项名称 - * @param {*} func 客户端加载项要执行的方法 - * @param {*} param 客户端家乡执行方法的参数 - * @param {*} urlBase 网页路径前缀 - * @param {*} callback 回调函数 - * @param {*} wpsclient wpsclient对象 - * @param {*} concurrent 请求是否同步发送 - */ - function WpsStartWrap(options) { - WpsStart({ - clientType: options.clientType, - name: options.name, - func: options.func, - param: options.param, - urlBase: options.urlBase, - callback: options.callback, - tryCount: 4, - bPop: true, - wpsclient: options.wpsclient, - }) - } - - /** - * 支持浏览器触发,WPS有返回值的启动 - * - * @param {*} clientType 组件类型 - * @param {*} name WPS加载项名称 - * @param {*} func WPS加载项入口方法 - * @param {*} param 参数:包括WPS加载项内部定义的方法,参数等 - * @param {*} callback 回调函数 - * @param {*} tryCount 重试次数 - * @param {*} bPop 是否弹出浏览器提示对话框 - */ - var exId = 0; - function WpsStartWrapExInner(options) { - var infocontent = options.param.param; - if (!options.wpsclient || options.wpsclient.single) { - infocontent = JSON.stringify(options.param.param); - var rspUrl = options.urlBase + "/transferEcho/runParams"; - var time = new Date(); - var cmdId = "js" + time.getTime() + "_" + exId; - var funcEx = "var res = " + options.func; - var cbCode = "var xhr = new XMLHttpRequest();xhr.open('POST', '" + rspUrl + "');xhr.send(JSON.stringify({id: '" + cmdId + "', response: res}));" //res 为func执行返回值 - var infoEx = infocontent + ");" + cbCode + "void(0"; - options.func = funcEx; - infocontent = infoEx; - } - var startInfo = { - "name": options.name, - "function": options.func, - "info": infocontent, - "showToFront": options.param.showToFront, - "jsPluginsXml": options.param.jsPluginsXml, - }; - - var strData = JSON.stringify(startInfo); - if (IEVersion() < 10) { - try { - eval("strData = '" + JSON.stringify(startInfo) + "';"); - } catch (err) { - - } - } - - var baseData = encode(strData); - var wrapper; - - if (!options.wpsclient|| options.wpsclient.single) { - var url = options.urlBase + "/transfer/runParams"; - var data = "ksowebstartup" + options.clientType + "://" + baseData; - wrapper = { - id: cmdId, - app: options.clientType, - data: data, - serverId: serverId, - mode: options.silentMode ? "true" : "false", - }; - } - else { - var url = options.urlBase + "/transferEx/runParams"; - wrapper = { - id: options.wpsclient.clientId, - app: options.clientType, - data: baseData, - mode: options.wpsclient.silentMode ? "true" : "false", - serverId: serverId - }; - } - wrapper = JSON.stringify(wrapper); - startWps({ - url: url, - sendData: wrapper, - callback: options.callback, - tryCount: options.tryCount, - bPop: options.bPop, - timeout: 0, - concurrent: options.concurrent, - client: options.wpsclient - }); - } - - var serverVersion = "wait" - var cloudSvrStart = true; - var initCloudsvr = false; - /** - * 获取服务端版本号的接口 - * @param {*} options 参数对象,详情见下: - * @param {*} clientType 加载项类型, wps / wpp / et - * @param {*} name 加载项名称 - * @param {*} func 客户端加载项要执行的方法 - * @param {*} param 客户端家乡执行方法的参数 - * @param {*} urlBase 网页路径前缀 - * @param {*} callback 回调函数 - * @param {*} wpsclient wpsclient对象 - * @param {*} concurrent 请求是否同步发送 - */ - function WpsStartWrapVersionInner(options) { - if (serverVersion == "wait") { - if (cloudSvrStart == false) { - InitWpsCloudSvr(); - initCloudsvr = true; - } - startWps({ - url: options.urlBase + '/version', - sendData: JSON.stringify({ serverId: serverId }), - callback: function (res) { - if (res.status !== 0) { - options.callback(res) - return; - } - serverVersion = res.response; - cloudSvrStart = true; - options.tryCount = 1 - options.bPop = false - if (serverVersion === "") { - WpsStart(options) - } else if (serverVersion < "1.0.1" && options.wpsclient) { - options.wpsclient.single = true; - WpsStartWrapExInner(options); - } else { - WpsStartWrapExInner(options); - } - }, - tryCount: 4, - bPop: true, - timeout: 5000, - concurrent: options.concurrent - }); - } else { - options.tryCount = 4 - options.bPop = true - if (serverVersion === "") { - WpsStartWrap(options) - } else if (serverVersion < "1.0.1" && options.wpsclient) { - options.wpsclient.single = true; - WpsStartWrapExInner(options); - } else { - WpsStartWrapExInner(options); - } - } - } - - var HeartBeatCode = - "function getHttpObj() {\n" - + " var httpobj = null;\n" - + " if (IEVersion() < 10) {\n" - + " try {\n" - + " httpobj = new XDomainRequest();\n" - + " } catch (e1) {\n" - + " httpobj = new createXHR();\n" - + " }\n" - + " } else {\n" - + " httpobj = new createXHR();\n" - + " }\n" - + " return httpobj;\n" - + " }\n" - + " \n" - + " function createXHR() {\n" - + " if (typeof XMLHttpRequest != 'undefined') {\n" - + " return new XMLHttpRequest();\n" - + " } else if (typeof ActiveXObject != 'undefined') {\n" - + " var versions = [\n" - + " 'MSXML2.XMLHttp.6.0',\n" - + " 'MSXML2.XMLHttp.3.0',\n" - + " 'MSXML2.XMLHttp'\n" - + " ];\n" - + " \n" - + " for (var i = 0; i < versions.length; i++) {\n" - + " try {\n" - + " return new ActiveXObject(versions[i]);\n" - + " } catch (e) {\n" - + " \n" - + " }\n" - + " }\n" - + " } else {\n" - + " throw new Error('您的浏览器不支持XHR对象');\n" - + " }\n" - + " }\n" - + " \n" - + " function IEVersion() {\n" - + " var userAgent = navigator.userAgent; \n" - + " var isIE = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1;\n" - + " var isEdge = userAgent.indexOf('Edge') > -1 && !isIE; \n" - + " var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1;\n" - + " if (isIE) {\n" - + " var reIE = new RegExp('MSIE (\\d+\\.\\d+);');\n" - + " reIE.test(userAgent);\n" - + " var fIEVersion = parseFloat(RegExp['$1']);\n" - + " if (fIEVersion == 7) {\n" - + " return 7;\n" - + " } else if (fIEVersion == 8) {\n" - + " return 8;\n" - + " } else if (fIEVersion == 9) {\n" - + " return 9;\n" - + " } else if (fIEVersion == 10) {\n" - + " return 10;\n" - + " } else {\n" - + " return 6; \n" - + " }\n" - + " } else if (isEdge) {\n" - + " return 20; \n" - + " } else if (isIE11) {\n" - + " return 11; \n" - + " } else {\n" - + " return 30; \n" - + " }\n" - + " }\n" - + " var heartBeatStart = false;\n" - + " function checkLastRegTime() {\n" - + " var now = new Date().valueOf();\n" - + " var TimeGap = now - LastRegTime;\n" - + " if (TimeGap > 5000 && !heartBeatStart) {\n" - + " HeartBeat();\n" - + " heartBeatStart = true;\n" - + " }\n" - + " }\n" - + " \n" - + " function HeartBeat() {\n" - + " var heartBeatItem = function () {\n" - + " var xhr = getHttpObj();\n" - + " xhr.onload = function (e) {\n" - + " self.setTimeout(heartBeatItem, 5000);\n" - + " }\n" - + " xhr.onerror = function (e) {\n" - + " self.setTimeout(heartBeatItem, 5000);\n" - + " }\n" - + " xhr.ontimeout = function (e) {\n" - + " self.setTimeout(heartBeatItem, 5000);\n" - + " }\n" - + " xhr.open('POST', 'http://127.0.0.1:58890/askwebnotify', true);\n" - + " xhr.timeout = 2000;\n" - + " xhr.send(JSON.stringify(paramStr));\n" - + " }\n" - + " heartBeatItem();\n" - + " }\n" - + " \n" - + " var paramStr;\n" - + " var startCheck = false;\n" - + " self.addEventListener('message', function (event) {\n" - + " var data = event.data;\n" - + " paramStr = data.param\n" - + " paramStr.heartBeat = true\n" - + " LastRegTime = data.LastRegTime;\n" - + " if (!startCheck) {\n" - + " startCheck = true;\n" - + " self.setInterval(checkLastRegTime, 5000)\n" - + " }\n" - + " }, false);\n" - /** - * 生成guid的接口 - * @returns guid - */ - function guid() { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - } - - /** - * 开启多用户的接口 - */ - var serverId = undefined - function EnableMultiUser() { - serverId = getServerId(); - } - - /** - * 自定义协议启动服务端 - * 默认不带参数serverId,linux未升级之前不要使用多用户 - */ - function InitWpsCloudSvr () { - if(serverId == undefined) - window.location.href = "ksoWPSCloudSvr://start=RelayHttpServer"//是否启动wps弹框 - else - window.location.href = "ksoWPSCloudSvr://start=RelayHttpServer" + "&serverId=" + serverId //是否启动wps弹框 - } - - /** - * 获取serverId的接口 - * @returns serverId - */ - function getServerId() { - if (window.localStorage) { - if (localStorage.getItem("serverId")) { - // - } - else { - localStorage.setItem("serverId", guid()); - } - return localStorage.getItem("serverId"); - } - else { - return guid(); - } - } - - /** - * 将字符串转成二进制,这里用来将字符串化后的js代码转成二进制文件 - * @param {*} code - * @returns js文件对象的url - */ - function codeToBlob(code) { - var blob = new Blob([code], { type: 'text/javascript' }); // 生成js文件对象 - var objectURL = window.URL.createObjectURL(blob); // 生成js文件的url - return objectURL; - } - - var RegWebNotifyMap = { wps: {}, wpp: {}, et: {} } - var bWebNotifyUseTimeout = true - function WebNotifyUseTimeout(value) { - bWebNotifyUseTimeout = value ? true : false - } - var g_businessId = Number(Math.random().toString().substr(3, 5) + Date.parse(new Date())).toString(36); - var HeartBeatWorker - if (window.Worker) { - try { - HeartBeatWorker = new Worker(codeToBlob(HeartBeatCode)); - } catch (error) { - // - } - } - var g_LastRegTime; - /** - * 注册一个前端页面接收WPS传来消息的方法 - * @param {*} clientType wps | et | wpp - * @param {*} name WPS加载项的名称 - * @param {*} callback 回调函数 - * @param {*} wpsclient wpsclient对象 - */ - function RegWebNotify(clientType, name, callback, wpsclient) { - if (clientType != "wps" && clientType != "wpp" && clientType != "et") - return; - var paramStr = {} - if (wpsclient) { - if (wpsclient.notifyRegsitered == true) { - return - } - wpsclient.notifyRegsitered = true; - paramStr = { - clientId: wpsclient.clientId, - name: name, - type: clientType, - serverId: serverId - } - if (HeartBeatWorker) - paramStr.businessId = g_businessId - } - else { - if (typeof callback != 'function') - return - if (RegWebNotifyMap[clientType][name]) { - RegWebNotifyMap[clientType][name] = callback; - return - } - var RegWebNotifyID = new Date().valueOf() + '' - paramStr = { - id: RegWebNotifyID, - name: name, - type: clientType, - serverId: serverId - } - if (HeartBeatWorker) - paramStr.businessId = g_businessId - RegWebNotifyMap[clientType][name] = callback - } - - var askItem = function () { - var xhr = getHttpObj() - xhr.onload = function (e) { - if (xhr.responseText == "WPSInnerMessage_quit") { - return; - } - try { - var resText = JSON.parse(xhr.responseText); - if (typeof resText == 'object') { - paramStr.messageId = resText.msgId; - } - if (wpsclient) { - if (typeof resText.data == 'object') // 如果发的数据是字符串化后的json对象,这里的resText.data就是一个json对象,可以输出自己想要的json数据 - wpsclient.OnRegWebNotify(resText.data.data) - else - wpsclient.OnRegWebNotify(resText.data) - } else { - var func = RegWebNotifyMap[clientType][name] - if (typeof resText.data == 'object') // 如果发的数据是字符串化后的json对象,这里的resText.data就是一个json对象,可以输出自己想要的json数据 - func(resText.data.data) - else - func(resText.data) - } - } - catch (e) { - // 这里做一个容错,即使json解析失败,也要把msgId提取出来,发回给服务端,避免消息清不掉一直重复发送 - // 同时把data也取出来,但是格式无法保证 - var str = xhr.responseText - var idx1 = str.indexOf(":") - var idx2 = str.indexOf(",") - paramStr.messageId = parseInt(str.substring(idx1 + 1, idx2)) - var idx3 = str.indexOf("\"data\"") - var idx4 = str.indexOf("}") - var data = str.substring(idx3, idx4) - if (wpsclient) { - if (data) - wpsclient.OnRegWebNotify(data) - else - wpsclient.OnRegWebNotify(xhr.responseText) - } else { - var func = RegWebNotifyMap[clientType][name] - if (data) - func(data) - else - func(xhr.responseText) - } - } - window.setTimeout(askItem, 300) - } - xhr.onerror = function (e) { - if (bWebNotifyUseTimeout) - window.setTimeout(askItem, 1000) - else - window.setTimeout(askItem, 10000) - } - xhr.ontimeout = function (e) { - if (bWebNotifyUseTimeout) - window.setTimeout(askItem, 300) - else - window.setTimeout(askItem, 10000) - } - if (IEVersion() < 10) { - xhr.onreadystatechange = function () { - if (xhr.readyState != 4) - return; - if (xhr.bTimeout) { - return; - } - if (xhr.status === 200) - xhr.onload(); - else - xhr.onerror(); - } - } - xhr.open('POST', GetUrlBase() + '/askwebnotify', true) - if (bWebNotifyUseTimeout) - xhr.timeout = 2000; - if (HeartBeatWorker) { - g_LastRegTime = new Date().valueOf(); - var param = { - param: { - name: name, - type: clientType, - businessId: g_businessId, - serverId: serverId - }, - LastRegTime: g_LastRegTime - } - HeartBeatWorker.postMessage(param) - } - xhr.send(JSON.stringify(paramStr)); - } - window.setTimeout(askItem, 2000) - } - - /** - * 获取网页路径前缀 - * @returns url前缀 - */ - function GetUrlBase() { - if (location.protocol == "https:") - return "https://127.0.0.1:58891" - return "http://127.0.0.1:58890" - } - - /** - * 获取服务端版本号的接口,这里主要是初始化一些参数 - * @param {*} clientType 加载项类型, wps / wpp / et - * @param {*} name 加载项名称 - * @param {*} func 客户端加载项要执行的方法 - * @param {*} param 客户端家乡执行方法的参数 - * @param {*} callback 回调函数 - * @param {*} showToFront 设置客户端是否显示到前面 - * @param {*} jsPluginsXml 设置加载项路径 - * @param {*} silentMode 静默启动WPS - */ - function WpsStartWrapVersion(clientType, name, func, param, callback, showToFront, jsPluginsXml,silentMode) { - var paramEx = { - jsPluginsXml: jsPluginsXml ? jsPluginsXml : "", - showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, - param: (typeof (param) == 'object' ? param : JSON.parse(param)) - } - var options = { - clientType: clientType, - name: name, - func: func, - param: paramEx, - urlBase: GetUrlBase(), - callback: callback, - wpsclient: undefined, - concurrent: true, - silentMode:silentMode - } - WpsStartWrapVersionInner(options); - } - - //从外部浏览器远程调用 WPS 加载项中的方法 - var WpsInvoke = { - InvokeAsHttp: WpsStartWrapVersion, - InvokeAsHttps: WpsStartWrapVersion, - RegWebNotify: RegWebNotify, - ClientType: { - wps: "wps", - et: "et", - wpp: "wpp" - }, - CreateXHR: getHttpObj, - IsClientRunning: IsClientRunning - } - - window.wpsclients = []; - /** - * @constructor WpsClient wps客户端 - * @param {string} clientType 必传参数,加载项类型,有效值为"wps","wpp","et";分别表示文字,演示,电子表格 - */ - function WpsClient(clientType) { - /** - * 设置RegWebNotify的回调函数,加载项给业务端发消息通过该函数 - * @memberof WpsClient - * @member onMessage - */ - this.onMessage; - - /** - * 设置加载项路径 - * @memberof WpsClient - * @member jsPluginsXml - */ - this.jsPluginsXml; - - /** - * 内部成员,外部无需调用 - */ - this.notifyRegsitered = false; - this.clientId = ""; - this.concurrent = false; - this.clientType = clientType; - this.firstRequest = true; - - /** - * 内部函数,外部无需调用 - * @param {*} options - */ - this.initWpsClient = function (options) { - options.clientType = this.clientType - options.wpsclient = this - options.concurrent = this.firstRequest ? true : this.concurrent - this.firstRequest = false; - WpsStartWrapVersionInner(options) - } - - /** - * 以http启动 - * @param {string} name 加载项名称 - * @param {string} func 要调用的加载项中的函数行 - * @param {string} param 在加载项中执行函数func要传递的数据 - * @param {function({int, string})} callback 回调函数,status = 0 表示成功,失败请查看message信息 - * @param {bool} showToFront 设置wps是否显示到前面来 - * @return {string} "Failed to send message to WPS." 发送消息失败,客户端已关闭; - * "WPS Addon is not response." 加载项阻塞,函数执行失败 - */ - this.InvokeAsHttp = function (name, func, param, callback, showToFront) { - function clientCallback(res) { - //this不是WpsClient - if (res.status !== 0 || serverVersion < "1.0.1") { - if (callback) - callback(res); - RegWebNotify(clientType, name, this.client.onMessage) - return; - } - var resObject = JSON.parse(res.response); - if (this.client.clientId == "") { - this.client.clientId = resObject.clientId; - } - this.client.concurrent = true; - if (typeof resObject.data == "object") - res.response = JSON.stringify(resObject.data); - else - res.response = resObject.data; - if (IEVersion() < 10) - eval(" res.response = '" + res.response + "';"); - if (callback) - callback(res); - this.client.RegWebNotify(name); - } - var paramEx = { - jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "", - showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, - param: (typeof (param) == 'object' ? param : JSON.parse(param)) - } - this.initWpsClient({ - name: name, - func: func, - param: paramEx, - urlBase: GetUrlBase(), - callback: clientCallback - }) - } - - /** - * 以https启动 - * @param {string} name 加载项名称 - * @param {string} func 要调用的加载项中的函数行 - * @param {string} param 在加载项中执行函数func要传递的数据 - * @param {function({int, string})} callback 回调函数,status = 0 表示成功,失败请查看message信息 - * @param {bool} showToFront 设置wps是否显示到前面来 - */ - this.InvokeAsHttps = function (name, func, param, callback, showToFront) { - var paramEx = { - jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "", - showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, - param: (typeof (param) == 'object' ? param : JSON.parse(param)) - } - this.initWpsClient({ - name: name, - func: func, - param: paramEx, - urlBase: GetUrlBase(), - callback: callback - }) - } - - /** - * 内部函数,外部无需调用 - * @param {*} name - */ - this.RegWebNotify = function (name) { - RegWebNotify(this.clientType, name, null, this); - } - - /** - * 消息注册函数的回调函数 - * @param {*} message 客户端发来的消息 - */ - this.OnRegWebNotify = function (message) { - if (this.onMessage) - this.onMessage(message) - } - - /** - * 以静默模式启动客户端 - * @param {string} name 必传参数,加载项名称 - * @param {function({int, string})} [callback] 回调函数,status = 0 表示成功,失败请查看message信息 - */ - this.StartWpsInSilentMode = function (name, callback) { - function initCallback(res) { - //this不是WpsClient - if (res.status !== 0 || serverVersion < "1.0.1") { - if (callback) - callback(res); - RegWebNotify(clientType, name, this.client.onMessage) - return; - } - if (this.client.clientId == "") { - this.client.clientId = JSON.parse(res.response).clientId; - window.wpsclients[window.wpsclients.length] = { name: name, client: this.client }; - } - res.response = JSON.stringify(JSON.parse(res.response).data); - this.client.concurrent = true; - if (callback) { - callback(res); - } - this.client.RegWebNotify(name); - } - var paramEx = { - jsPluginsXml: this.jsPluginsXml, - showToFront: false, - param: { status: "InitInSilentMode" } - } - this.silentMode = true; - this.initWpsClient({ - name: name, - func: "", - param: paramEx, - urlBase: GetUrlBase(), - callback: initCallback - }) - } - - /** - * 显示客户端到最前面 - * @param {string} name 必传参数,加载项名称 - * @param {function({int, string})} [callback] 回调函数 - */ - this.ShowToFront = function (name, callback) { - if (serverVersion < "1.0.1") { - if (callback) { - callback({ - status: 4, - message: "当前客户端不支持,请升级客户端" - }); - return; - } - return; - } - if (this.clientId == "") { - if (callback) callback({ - status: 3, - message: "没有静默启动客户端" - }); - return; - } - var paramEx = { - jsPluginsXml: "", - showToFront: true, - param: { status: "ShowToFront" } - } - this.initWpsClient({ - name: name, - func: "", - param: paramEx, - urlBase: GetUrlBase(), - callback: callback - }) - } - - /** - * 关闭未显示出来的静默启动客户端 - * @param {string} name 必传参数,加载项名称 - * @param {function({int, string})} [callback] 回调函数 - */ - this.CloseSilentClient = function (name, callback) { - if (serverVersion < "1.0.1") { - if (callback) { - callback({ - status: 4, - message: "当前客户端不支持,请升级客户端" - }); - return; - } - return; - } - if (this.clientId == "") { - if (callback) callback({ - status: 3, - message: "没有静默启动客户端" - }); - return; - } - var paramEx = { - jsPluginsXml: "", - showToFront: false, - param: undefined - } - var func; - if (this.clientType == "wps") - func = "wps.WpsApplication().Quit" - else if (this.clientType == "et") - func = "wps.EtApplication().Quit" - else if (this.clientType == "wpp") - func = "wps.WppApplication().Quit" - - function closeSilentClient(res) { - if (res.status == 0) - this.client.clientId = "" - if (callback) callback(res); - return; - } - this.initWpsClient({ - name: name, - func: func, - param: paramEx, - urlBase: GetUrlBase(), - callback: closeSilentClient - }) - } - - /** - * 当前客户端是否在运行,使用WpsClient.IsClientRunning()进行调用 - * @param {function({int, string})} [callback] 回调函数,"Client is running." 客户端正在运行 - * "Client is not running." 客户端没有运行 - */ - this.IsClientRunning = function (callback) { - if (serverVersion < "1.0.1") { - if (callback) { - callback({ - status: 4, - message: "当前客户端不支持,请升级客户端" - }); - return; - } - return; - } - IsClientRunning(this.clientType, callback, this) - } - } - - /** - * 初始化sdk,用来减少在服务进程启动时自定义协议弹框出现的次数 - */ - function InitSdk() { - var url = GetUrlBase() + "/version"; - startWps({ - url: url, - callback: function (res) { - if (res.status !== 0) { - cloudSvrStart = false; - return; - } - if (serverVersion == "wait") { - InitMultiUser(); - } - }, - tryCount: 1, - bPop: false, - timeout: 1000 - }); - } - InitSdk(); - - /** - * 初始化多用户模式 - */ - function InitMultiUser() { - var url = GetUrlBase() + "/version"; - startWps({ - url: url, - sendData: JSON.stringify({ serverId: serverId }), - callback: function (res) { - if (res.status !== 0) { - cloudSvrStart = false; - return; - } - if (serverVersion == "wait") { - serverVersion = res.response; - cloudSvrStart = true; - } - }, - tryCount: 1, - bPop: false, - timeout: 1000 - }); - } - - if (typeof noGlobal === "undefined") { - window.WpsInvoke = WpsInvoke; - window.WpsClient = WpsClient; - window.WebNotifyUseTimeout = WebNotifyUseTimeout; - window.EnableMultiUser = EnableMultiUser; - } - - /** - * 当前客户端是否在运行,使用WpsInvoke.IsClientRunning()进行调用 - * @param {string} clientType 加载项类型 - * @param {function} [callback] 回调函数,"Client is running." 客户端正在运行 - * "Client is not running." 客户端没有运行 - */ - function IsClientRunning(clientType, callback, wpsclient) { - var url = GetUrlBase() + "/isRunning"; - var wrapper = { - id: wpsclient == undefined ? undefined : wpsclient.clientId, - app: clientType, - serverId: serverId - } - wrapper = JSON.stringify(wrapper); - startWps({ - url: url, - sendData: wrapper, - callback: callback, - tryCount: 1, - bPop: false, - timeout: 2000, - concurrent: true, - client: wpsclient - }); - } - - /** - * 获取publish.xml的内容 - * @param {*} callBack 回调函数 - */ - function WpsAddonGetAllConfig(callBack) { - var baseData = JSON.stringify({ serverId: serverId }); - startWps({ - url: GetUrlBase() + "/publishlist", - type: "POST", - sendData: baseData, - callback: callBack, - tryCount: 3, - bPop: true, - timeout: 5000, - concurrent: true - }); - } - - /** - * 检查ribbon.xml文件是否有效 - * @param {*} element 参数对象 - * @param {*} callBack 回调函数 - */ - function WpsAddonVerifyStatus(element, callBack) { - var xmlReq = getHttpObj(); - var offline = element.online === "false"; - var url = offline ? element.url : element.url + "ribbon.xml"; - xmlReq.open("POST", GetUrlBase() + "/redirect/runParams"); - xmlReq.onload = function (res) { - if (offline && !res.target.response.startsWith("7z")) { - callBack({ status: 1, msg: "不是有效的7z格式" + url }); - } else if (!offline && !res.target.response.startsWith(" - - - - - - - - title - - - - - - - - - - -
-
-
- - - -
-
-
- - - - \ No newline at end of file diff --git a/oaassist/server/wwwroot/resource/wps.html b/oaassist/server/wwwroot/resource/wps.html deleted file mode 100644 index 3e68c5e..0000000 --- a/oaassist/server/wwwroot/resource/wps.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - title - - - - - - - - - - - - -
-
-
- - - - - - - - - - - - - - - - -
-
-
- - - - \ No newline at end of file diff --git a/test/oaassist/.gitignore b/test/oaassist/.gitignore new file mode 100644 index 0000000..0076954 --- /dev/null +++ b/test/oaassist/.gitignore @@ -0,0 +1,2 @@ +# WPS加载项快速上手说明源文件忽略 +/WPS加载项快速上手说明/ \ No newline at end of file diff --git a/test/oaassist/EtOAAssist/LICENSE b/test/oaassist/EtOAAssist/LICENSE new file mode 100644 index 0000000..3417144 --- /dev/null +++ b/test/oaassist/EtOAAssist/LICENSE @@ -0,0 +1,25 @@ + +Copyright @ 2012-2019, Kingsoft office,All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +2. 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. +3. Neither the name of the copyright holder 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 HOLDER 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. \ No newline at end of file diff --git a/test/oaassist/EtOAAssist/README.md b/test/oaassist/EtOAAssist/README.md new file mode 100644 index 0000000..490a26a --- /dev/null +++ b/test/oaassist/EtOAAssist/README.md @@ -0,0 +1,19 @@ +## Welcome to ET OAAssist Demo + +### 这个项目是什么? + +这个工程为WPS表格项目一个简单的OA场景集成的WPS加载项——OA助手,旨在帮助大家能够快速理解并熟悉WPS加载项机制以及和浏览器调用交互的流程。 + +### 工程结构 + +* icon 图标文件。 +* js WPS 加载项功能逻辑的js代码。 +* index.html 加载项的默认加载页面。 +* ribbon.xml 自定义选项卡配置。 + +### 注意事项 + +* 本工程只是演示demo +* 我们建议您结合具体的应用场景修改示例代码,这样更能够体现OA助手集成的应用场景 +* 为了保护代码,建议代码上线前进行混淆 +* 使用该工程的时候,必须要安装WPS专业版,请咨询QQ:3253920855 diff --git a/test/oaassist/EtOAAssist/icon/w_Save.png b/test/oaassist/EtOAAssist/icon/w_Save.png new file mode 100644 index 0000000000000000000000000000000000000000..edcd53adbae0b94fe56289cb590884a0a375d082 GIT binary patch literal 13913 zcmZ|01yCJb&^9<1cP{Sk?gZ!J?gWAacXzkoZoxIU1%fBITY{6|?(VKX?^j#3-|p7d z)R{BW{dD)~s+p=YPxnNrD$AfE5h4KqfGQ^|ss29W|2Gie-p}iv!uJ4xr)Vu9p=xbv z3IJYE(p-8N%rYZ@>zzMsPnBc!#@ipvd{dndt+S>Ved+1o*bXRkDx&rvc{Jr-g3`ZrW zex?k@E(l6V4xETP>qa=LI$l9 z0YK)rw{@)7E^oM(ExD5Lx4ytTC;&j&O+vijwpo005_mm}ETDPG4S@zSOs(T@fo@db zibB&>5CFpjjd^7?yqw{OigM5PouF$+qPn;}_M!Ier`2?wN#$%|DSZY7;Q@#-DsCQc zMV6&98T?QH7vRFp-LvVKe@I_h%>~o~I+UP(c0P(?0USS4;Pyz3+q#LIeA&4=JjSqeNlvwu5pdgeWjF|Wa*Oy%6B3KVdh^j1GswRyU>!rP|k1r ze??8*5W+%(hK~ceo@GP{`$3;e^j+3IiZRJ$OKRJ}lkT*Fal(06>fEMlxH6HU`5JsKW3} zLiw}9A=kpvIl+^iM;Jv0;eV4rGK1i5i(wE4n>s;NuA}5c#7rWcOrmx;!JqcgD|WkP zeBr+b{+#3Rf?+7gsY9_gBqYIdlB8-9ZeWRis5%*a3^HmkqKrurH8u2zSaf3FFk&&B zHAFX2xfrh{CYC}aNyiNI5c}M1#4(D`DUCoCrZ%{5q{!}p?>UO5$Y()EOY${_KeD3x zuL-NsB6~;1QwHKF$}Y48D)J{<<_}ufRgwRCvW#&E6;kI8Q_ zJmA_QU*b2_lv9Ek3m?mQ4!^(^2~H_C;tPMtlUbSsU1JEuuoh+WVJd^^5@z}q*4v#o zeqrmA)}Uxdw1v0DWp|HlbZ%aFIka;d5IM%(^~h{^Zp2)aou{7*-*Y_MJ`;X{tWynR zp&%&3Fj6EX%J3=wg8Y)gryIrS?HB{R(JV-xM zKD6JD-Y zO#^nuyp*C;r}S);c+_RoVl-e>ZWKQADAPA1pYunuEHy(i$4GjLtbnWy`OVi-xwTJx zIw_y*K8b(2t<|h=tcz`6uH&qiug|J|Y$$C=t1~e6A8s8U9Ht$x7?d{uV^(E$WR`8F zXS!#mZSHB3V9aLWXx8;dWI}8`akF+EVPklQuWxGNA`9ye!?^Vz!DwcmciI*29x;JR z8tqbI(XiBZ%r?d)Cmwt{TsoaLqc+VPY7Kz{^H1!bs2}3mLfcZG5bw}QDM+#MRP&(n zEb^T5+zmhmrmL!};;RbnSnZRWtav| za!MRdv`Y4(9igwFBB0P=<)?39rD55jNoD)T%ELCsWKWgLx)?+FjvB_>km~ ziSUxJfUu0Gl$)Q2g!_u;i968R+IFfbs|mM}rV+YH#YW{Y(LKjK+CALOxwW*_*R9RH z>&W_m=CJ9|e_H!*!mQ)p{59GR7PqAZ`yZ(NDCKZGa9rWoeULtzJ_0H=s!Fx$DJE0r zE%27WmM3jJtr{(!Vw&Pd#e>p0#ksNTQIG7K4AZgdQRFchW8_qSscNh6je2rLCrF@9 z5K+-m5uJdWaA$M<(PzN5`g^slS^ZL5vCSS6}kpy6RHD>2s%(bx4h|Z6M6QxuVR0CEP8f&$i!nM;=`Fk2}4QI z{P8Tn9(;Bp%jD0p_u`>yk~;k+#X8$j!>RN~<(1_(R%QE-`z%>_C+a8?ibjf-%rbUv z$B-N+eVgS^?S6g+&!fs6xkDbTGbj7*h_b!$q4AO~CVrbv$%@mR#S3PA+rPIR8S)sk z)fY5OH6muVr;(;tOY}hwR{y0_WF@6?v@Mx=D$ynrq%8cD@l!d?Yw6JPov_4c zC~P2oe_zSQUz4{|XHuC`+CJRfh*bG2c{6)ow~zR}JXgN#zYf1p!5+d6A@d?jAf4e< zV5j1|Fr%?{dO~g>17E5`jNxVE8|9VBddZ@NuZ#bdUq2h)_8mkRk~#BDd!)EDp6{od zf`(4htW!RwV*UC0+mi8^Ng!T*D>+br6Y*!&q^pPtUgytsMRk96mvZkqG(EB$Z_6XInsl(T!nR|! z?&YT8VbMQtWA~YQHj!yCaUG*MRgg;GaGBn@WBJ0OqI;tIRI{&d-O1>Ev&}PZ8)h%7 zr@Q3hEBT}tp)&NT%-+&4Jz%csNPh09O{$H_(P@RgMXo*5*Y!y2vAQYmK5t<4e09zr z74o2Z`DZWh7&aalbZICVe$bGM!M zg=hC@&}ZXAr{iANkssOf#?97>^lz2kiD<+6u2$X?UPHS9JNp5R15E(vh5~4rQPy3B zff4v1SL~qqtEcQu^jZV}4oH%Gn<#18yZ&JLEWyAGLXG-QiIk$AIcjC(OB= zD_R{KFYeH467WTKTdZHnEEabwaG|w`XEn1emhx}M(VF6`#(7!G^tG3jgl~OCE^%+8 z&g~aEJNxFl=#4^u<8EX6@ohWfTmI7Me;r;eH{`y_D4);zg(ui@z>C<1srPlYEV9Hw zMKC3R4!U89kIP2l!i2=5n;H1-LrNWiz3^`hj2lKZ|*8I%Mc z(ikQtdQt5uf4}GcrQc&3`eh|mZk6^neztw%{kdbp+8;fe0=A#q!mDZXkQwn#vP0NP z3|Z~1?M}Kbj}O&}YCacBG|Y4|JwJAy9umzt#INX{(%djy>!C|7i#Y8~ub;d>f;V@+ zPxnxUMCL_I?ozcDmDxRp=RWy5>t*kWf7BKMQUl}6AAPwnL`6xg@V`EZIXl25MuYXCePX(^=8 zNE2W#Fk(0IoavS|@WuRVQzlDLZmxe2Rh&kuYo7j}oe7p<;Q@{DqdvOPpWSPewR)2} zvYJ*B_ffJ;C8~c_6m{%0o}(mVwm}v2*1iM;I8rn9WuR##7^q~nG`|wgIJ^E8U*cRnEWGj6lWY6*(20A*6Gz)%*5KyuGV#}jfO%tcv<)z z`BC(TR9X@dx8ehYPWdFhNF45=aY4foP9?oH{ zbB5Q;x%}~T!}sazj6m5JEQ)!{?&LOm@m$oz#*!A{B7E8JTF-X_(tSW;@)I(h(uvEUq8KC8%3n*$8Wz4L(_-o zfX{~cPrMf|;|b$&;rTmVNW3#YkKc3xMHJD}LdRrUrnvY%FSCn;24Pkbj1sJJozgLa z=`!mxa5D3gU34^cN_Aoun(I1Df2`MT&9B>$`#Kx9)VM@kCVKmLncl-ZoSxGmL?WRe zmm);sE)QGX za4kxM%TL}$wMLv~)8;1!(KGfPuZfDKhr&PBbLu}|P6&-{e+v_o?6b% z&+pLA(XI>N;HQGOBsRsN`r(g%ynZVqwkihu6`Cab)O$o5 zR2pYVwXU%4q0FtEW_J2Q-JT9#PTc;v_;a(mm$R2k)+E~Wt^C|f&DHtt3p~7~LK?a~ zDJ=w+OF99pGc4-2;{qu83eAq>j-LE z8%lOY1fr<$8V~>gaQHzap<)=Z-6U3t@RmlvE|{_~{GQ?|3C#>d6?)N4+`rt%X;fV& zHP4YkhAO5v$&!P0igGHrO0XsiLDUpS522Sp>k}%1HbqX#&rr}eyEHj8)iM>4qD)Md z{qZU1lSA$A2CZ6*dCYl>h1>;4r(su3r%k@Ee0#$V+Xk#SH8u`tr~b=p-c~|f?IP{y z58v;7?tfnVM6^P5LnK7HMbtr#L-IwQh?$e#2luM-1rOu@hRY+AJ zlJ81mNc)%S&*Z7Nsvq#NKzYhAO50kq1u`Ixqv=?FqW0lmx6QTn=}i3`?rhIK^MUf= z&4J;9$M|~rhDZ_i7X4SF84?SJ-C5kyG-<8D*+JgHW-X8L+fKBC_zPwJ@f}u{8qXCA zVX%rd8~hn|zV4cw=q!oPYY#{U`l-CCXPV-*V8 z^G$wMmO<7(spc1xsHw<|-$X?R(Lx@7?vvyt=T$xqK8^v?tswm;PBour*-4Iz`a7I4 zI!+aVoZatP)z*R@>}VOP6M#r8Fze>)ecWYXCKUseT-L+l?6rv z8(@xnV^?RC+>!L{7wX3yxS|fF5ug#K>5@-XI8qQzUtnTlc~WKlm`5pEocN8t^8OQp zw$A5=IQf>!rbD(S-kVRTh;a;K61r%M%ZrBY1_!HiwlhE0JbJ%%v#&&25F2fpADUR$ zI~Wz%R~VNVSDP1E+ZtI~pB=9s;qRvG>L07``TVh;_FvH${_|IGu&mc}9{s1pz#0>| z=sDxfM|S>x0dB7EG|%?MUf4XX(Yz!~_;}zzhduRRT@&4D2$Djj<>JV73rh8hcjlI_ zRK3+gZcDNM-}c>SGFY^*>H%K(fYcne8_`}*w_nU<;!pRw=1UdxjG2cIi+?ON4r3== zdE0FdJH3w8T@)s9+H7@CDs$!McpUJTFHcbqKD1N|3c7A4lt zUn*N_zKgxfq7Fj-pukeadBnnt*UW#rLTnaqp$tEsu&vH&UxT+iAhhI#>pgJ^d!cZy zfQLkff?3=v_R8foKlH*(z<1=ToKXaTlWYj(z#VwvM z+AOv#(eV*`v>#qC!=6=c;I12NI?o}$Q!)!%g8M^FeXF8e->94zWO@0hi&@=7^cjP3 z7jWXHmrZRBh$>T&Evf`}+DcmE-+Ko;d;7=< z>1AbQmedw61|(koFJpg~7X>fdpMx)ahtO+cl*vfa>_iDzs;X5*utWoONuH+LwVrug zR<4Pbejc3R1r$5ZKW{%gT+UUDy;idXg|fTz001OI3FI`Rr&py8g!Tbl@;{q-ZGJWf zoqp765`m z0pRgn6toWj?(6_?XaoQP8SmV?Q%C}8)=~ELT>|eWrz8cx1wsUv zD7*X!1m8(}J|E3bZtBLKb+$Pf%iL*s=Y0Kl!? z=bV)OFa&PyCWLN7P!IqCb-zAzOia!%h^dN+!M)<`9528F_jnr|9f4N2fuB0x8g?UT zOUDPhv|l7XJSyhIoxCvW{+DnpNzU`#I9{L|oF`s{s9UC}Tgt@2hq$ij4}l*u-k4t2 z$*u$Ke~`a1%BF0WRc`)>2;$&&<9uTf55z}Ujvafmy57FCmCdh?Dq#VD`d1i&A9Y~` zBaXh?`4p4$4VHI!{;!ARB2Q=Bmv06dPam=Z!ozppnl>G)t|l-k)5g(w!}H#bcHZ9X z$X?K478;yiCM3ijuh^S;>jOzB8rROkqY5Ig$;9r&lc zzAxY1AsKMdag=o3#3G@wiobmu%C~WKQd50+9bZ2(r(k}XOANTi*06kFBgFYcAb%jb zyFV1Eq+BEaxX1mvfX26eT*@4{ABX~1doV)xwdr8)Yg#CISD_Rwe7=#RY2B|)K@L~Z(z+Hj{Hso-RxB{?(+J9Zx zxoC)022KGHG6*>YAHofRf-pjGA*2uv2rNW6h&IS0h%`tnh$F~42p&)o4Vvpp7-sC| z?FMxdbn}ptlk<@aLCheE5Fv;<#0EkOL4&NKt75CdsUoUkO#+j|lem*Olkn{L?1b!y z?8vp?TFhFES}dn?=o}b7gnLXU3@5B}gmWZ>_wpM8ECLyr089dgPb5#|PDD!VL?0#| z#u!GXhoQ%%hb~7bhbu?50$UO8GfYBF@=h|a1MJ-Fi|~pFis%{8pYT7SeL|i`nMa(* z<3r*@{e|!g_ZPAk@jb^m)cH8PA0iZ7Fp4-Jer9Px1JM+V6(bh&6ElI-zo)whk%o|l zFb9yslmGm74snK5h_ygy#CRZMVk=^OkQvAyh@O~?SpGZvoab+3WMpNuZFFpeX_RH8 zWwdIAz{kf&%Xb4mj;@ck3|@v6LJ`7hhigZF#<*v^hlSyWA%(#T z#Sg^|Ws#hOPl9{j@F8Cyn2>A|VuF&flabZYreUVBIMM21>XBX0TyQQQL&QTVBR1hn zpv+-$5K=)Ok$I4A;12N#39}HguyipNF$DmDtq_NxydZtmh^hAA59ASmd0au6QjOh%GNF0SC zhdlzr08@c)jc-jrfS-x4gTH{!e=or*Mk-|>1(KkUNs_D+kCLv4;EZtziVpo9Tp51& zB`aTAE7Yt7L;%jD)SYZ@5QTJo;zw3brt22kr~TBR?E(I1qjiff1$_ae=*c zXz3!!QO$wHvBa^~2h~&9tKRQ2^m~ACV6jK~p|+(iuCAyyyVh_6*ihY|-|*VP-Wpxc z+3Xvji=O})(smmA36ilA)&Mm)4oD7cr?jM;q-=RK21o{EtGFP>FXUfP#o&4ndU|9c zCFsTWtDR?PKDi_OROKQqolX75lz}FEtBVB+mK!~d{lnMP2#aY`p4Aczp6|mL< z2Yd(o1pJu-I(#~U3vm2!Ez~V@G6qVo;ZUToWMNcN7z0@H?DA;xw!i&S(946$KUFZ7 z*H`S8e-W|awNW_q`-^T3vF5Y3vyQgPn+YkPlbwh&;OUUk<<=!wBwxHu@JNpjRgPgz za>zMN`;yudUJ$y$Lxov{Z3;HU+rq%Y`O2YjJ9HgNK-z%cK;{a6MS;u{!=S+W2U*KZ z%lrGrcZu(J^YaTi^ERT*N*h(SUKNv#B&02gmcpM?etmomGphd zJ_tM5o-&@IlDd#;jTdcKdoPlJhsRfPEsGYiWA zTMc6i;~9n@niHxUHXhaz`htia2?SDZQmRol6v`G>7U~o_4n+2k4pa`H_3I3D48T)E zXo_htY4QS-@2TTxm}t<8=S!aD;$-_|nG`JL*hW-G_(t4Dpp)rn*mPF2RnjzPwVGe< zs#8)F(tK6E==Z1<=wT?TiE-#TD@Cb|$XM$WJZQ{n)ToPSV5moFcvs68999Yx!VI^{lp zSDBOknNOONS76WpD*w_dmf90nkYk**QIS-v7C-f+uGYEr;?|PVDA}am`u7C)h}%kR zzE1K&IKSwX*_9HqNDOxjiGuMT=0ANC^1X}`hs(O-t;>(&(krFoq@lvlzPZh^&9lu^ z9=|+DJ4$+tjjnpA(sB*B&_sZ2-~qtVYcN*g+xE}ZudMkYIawT zzw8?yacs%$5FE6e((HabMBTJM7T%WF$J%e$S2@4Z-bdcI-4@)IImX-kNk~qrih+P* zMZ(7xNkPxBPyI>w7Zc1H9wxY+n2}VM1deDI`&KANP>2nRx|h?0H<_Q4>yr03wGCs| zMvQVyXB0<#X7ms~8`bLP?>fhJ#CrM;P@jVBdmAJ>`=hD*seiCp^XnM6=pl*8YyOt2 zG&nRPRM0gL&}_AR6c1OFmZ6oi5Z@h3H&43Z)}wD@g{PzA+!M-|>y&AMYH9Mmzbw3} zL1IQWz>dai_Lnk~vK}xRa2T+qv7y;2AudTZ|71R8e)rq{4<2I*qcr3Dms=NOPUSC~ zZ#Hv>V}!X`@Hdi&?tiDNSiVbC#W(;~PWJOQ+*W?KJaQjUd0e^YniHG18!3NEH-VbH zn@Jk=8rj^eJcN!@4v7ypUt4wCtlR$hBKX!n72L)gg&m?EbR1nB3X(YC&l7Ny>6177p&b#xxcY9z^Av-BxkR3;8Eec6NSBzl(qM>p67CY+rNZ z`XsZX;pnOyc{C&F1UUs$ z2m2x6AdaE?;FS{Q?Z7L*wIQUxw-(5T|BBWOJC5v)cL@^+#f_^87mIa{T!_JmtA5x> z+|Xao?jMWT6DL=ag?Pzx%jk)OZ5_!g4!bw_8;o#Nu<~r)E%R z?9^G+9@Z_?!@Cqa^EwM}i|onVU;N%e#@xqj$F#t^0Fz+IB(tY{Pi;+7OVpm)qwXYGU>ihjmm36_ta{n3?$Om1=S#Xc+6yL~p6hVDUj#TK*w|^ZI;R|`G_5~|M zGTd}>mX7JPb1a^e=qIA-j#r>dy7i+2ZT!hc*m#%@gjJ*#q!2u1;vSL;VsnfWHd-zN z-{Y-c{!vD9{UhxRHing-b@*k- z`0RY<@j;ak&eYu!_z~VeSXsKUtIg78|Lw$!E+0_Vt_>l8(t8f}= zX6dcCe{l(~%w`Xoi*Dz!CqgGW2afSipc{!;nZyJKGBP0@FM&I|ZSSp^_Vl_ReujEo zYQ8GxEMtP#XDcVYhns)ZS6r5(w<>3|h6Tpp9tT%;A7__6=9GInYd>cT@0h3mVW8FU=MAd z1$Y-Ta8yE%YQbvpPqY6HWZ&xG@4DX!<38@j>*iJQwaW$T-NDU=3D2oBJ}^B3PlkXb zy(ZHrg%Eckc|F_V$LkS1bOYv(IkLgZg|_PAF7CgL4r3Z~Q4$ruGiTWa@Yg@MxmI84 zcLoplP8XhT?$OAYv+tPUh^K~s6!~Y(qja-t<4N?5a3o7IOQ|a@aW=VmGE6^>&xg))@sZv~UI_Q!^iaK>=V8Kt)iFECk>0|(Zj(}y z2@^M{eC6__3S{JzTNM7ukti3vP8Ah z;@1eDW+s&77~=n6$PWTqyG43r#D#llD4h#MOe{7TG24@`i=6_E6aJ`JNUS0+Ftm_{ z`9!zKNBzcN6se52(K@ssq|Fl0tz2XjV0_dR{fycnIt&mJEj)|Ad6dFgFz#M5hq5eu z-~V1=H++)xPGfI85hD=G<{semf za};V7${1=Lswd?oDJ`=jIX8ISpN-ds@0sY74Z}uYh}6NBDySs%nWc|;hK7k=kf%(* zuxt6C{U>ah)Z{=v4RJ}dxyR0wp_GHU@yE`?q1FMQU$OS@*XJ^zuZ z@fNDI005l&q5u#l1pp=LK+rE=0KnFI=UOrY$*16fZ@q{BA2vMjiR2Lk{7yK(`-Akn z#Sehry35gn-o6#{ih>*Qjkcjb!G=D9z6u0k1d#+~i{i=LL_jHnBmf0K23i!R2Z{q^ z{R}yU>_B3~*aCG}KdzIDhS~zbU`l)wXmwIEDr{U$guiHwkMP1UeK23qN%@4dy%cI) zYG2;@d`@sTMh*rp1`ha%LXFCtJS1TF6<%LWnn2PV!UB;HN0w@n{3&MGJ=vephdo5x zz1d^aXYo|q=H%rZelEA}8&vhBEqX81QwA&%sW7idE!QY}tQ0IhEn9h>M4D9c^(vX| zy*tT8y+*A>Jw}ymCS_`-WZ+(BMix#@8W;>9`%2aTMrQv5wx!QT5oCo253%mK)=->U ze^SOOOB(t0$P9;AclIQg%?WAYil z5w^4np?Z!{R__ToiT)V<#5Q0wd_JGCEIG%$VwVS-QF3pIV=a6ZkyW{X!*|S&C?M0; z?rQ3saP74vH6gfc*{9vlX4rj$SB$$%5RJD>^vambR>>nxhf8;AZDLWc#^}7LC2gPP z7~ihH&E{BFTg_MZw^+Y0xtXwJ_i<0N`a^YNyZzEW-%0p^%rc#z)g9_n9B!t zN5&Dh2ywXXYZYZlif;C9T5?Qswr|4SLfvJM^C0S=-k`xCia@6TfpbcP8~9CFPPAx{ z4QLS-4%q^c7fl(F6tNSv0GNV`LMA}-Mks;hxe#j*$9n;98D(&J?VcOFFn5y^GwI_% zafstmLYeSwvLq8tPes^8wMQ1lU7~!%bw^S{u?Odp`M|>oN(<6*S+L+zX_4?!c?{j{ zZF7lO`>8nJIC)<9A&?_-B2*y22dHkMIpZU;%F$I29xS|LK0Me)2jye&$n1zIL4?J& z6cZ9xu@=Ds7OgnpZqkT@zGNCi4J^nb=rRgMUx(rc0|x8*`N#eZejfiiz?M80Ga(I8 zQGLNu$4&!p+_gp2MK;LR%GJwXe8qi|vS~CM+ZMtx!Tyu-n35mJxMy?!H;nt(+QMpV zKj_eO^5Y!x2P+PJPHB!L_8T5sZo>xZ*Y7CRS9Yt5oAU?!DFUYgTrFO$@xS_f%Ds2J zsvm0~kgxo)gYIA#Vcf&Jk$F(6P`jd2@cv;_5u6$5OBFhBTKrbjb%OKVwf0y_pWsa> zG%6}D=B#r4-hGI56Btb8|gPl7k~?# zHo5(x7sU2bU%M)P7~+R)4%77bk}Qj6v}}C3F4bGugWEIJb3;K-`JM7nLR_p;DlMWN zodzTIMZ!M>H)K4dGej-eI#eq723rtU28xWl6Qpk_L;(d3cJ76tJW0q1zE3gB;Eo&3 z($9d3+e~x`ugnohl#U=}W5FO{Ut#Q{Htk4Y$mLHQi2axr7m=G3lKYh`9r#I|ARsDX zU@P+Bi&2kefy>6Oika+n#e6eNBy~7;RbzB)Lp${XZp&StO_Y?53XQV6I*F>p`ONhU z;hfk%x}u}1IpbPeNozY3b&FPGWea1|1#?uBB9kAJx7)6X9?Y(-u2XI&ZbR2jcYfPr zn_u^kcP%l_$s=j_*sys=S)On37)W{Wi*V0`SUHmT4?3{BxC^hR6p!qVb9(f*p!R#m zO{&yWe%KXKev7X5DKoInm7_ABaZu>soj^NaT|O-eXz)J?$&(=6ppL6@0_OMRh1pl6aCGG(yL#R z7j${rK9N7UAYmuL^pjDQc`s1Bw=~D$X7#;4E3AH7YxiVZJ2^L;U3cX* z-3{#EC69exy*XJ~;dtTX6-ET!i#01N?o%r(9h+p`y8$It36ubH4l z&kd3{uQ$gTDhdwUGz3VN1TMk|+v%n~xtP{6>2fHmoDa{_B?@azy4CIsG_$&-B7Tugyjb6BYU*2Cksvy0 zDduwWQ4T-<3=W2qp+$6|NA#`0qmv$g?)1yd%_TWqX^YVRz6)(S>Z6mUNQ)I+XvB{1 zU0ynyp?aFR^3d)s?KnRWUAR6FgBJ?s3w#x#fH8?})U8Gy%=qEB+RpFr zbIG^Ez|jEuOn6qe{Z5vlqB1(5OGOPk)5zDC=u8+Wnu>gR@fSzXZ}-AD^RHQGaotGt^YLRSSXF)_hblDaj+6ohNFWt9;U)xaU;i~dyl7es1ta|;FOi&M zdJj~b@(%1MTXCQ&8D%6)7>XU*!g@^LpbTBVzrTk81-YVC^DOGdG^JHmg2ln6#Zy*J zFON4u#{cEXKgXjQo3!DSfkzqoZOST#+G(64drVcnAeE98a&$7+U6#8~s4pJ{rkofP ztevGS>1E(K>!2Et6sIhfte8=hAP>^vfp%>8+i_=gCQK13mBp+r`Wk9GCqgyY{f1bA z?dvOg{%1n8plO_Pl1HPOdWJpcq_IJ~J@D(WRUCFOHkJ6er&Vmhg574w#5x6x+vnO8 z%qYoN#4~6LNi_5XJ|Uq|^=eaB(~y4|wIQIm8~0HkJPK+KDcNq!(g3|4KLi*uu=unU z_XE5Lf?RBT3MPegD7q}g$Zi|=Yc)&{{Ij}V9(hn@efccXL9QpF?pIvgzT}R4`E~#9 zi0Q5NR{XtKN#iE<$<55z&0N6L#r%B& zIN3S)S=c#P*!eZt+20!g1h}}F*!cwBuQ62d{vQVRj%L;t-v9pw3X1zx?*s0fFTyC|y(|gf{(m9b)@E*2?})$&nQ!k1g8zk3vbHz>uVf4S&zjks94tla zwUqx~k(4ywQ2+-IH!nXg4<84&#&P8GI|So@`O&cUF$X^Ia&w8}|H&>dm7~2mo2RFzi=(3(n}fNhtF_zz+_Rb+yLwxjIy$gAn7gr=nmMpo+gtwM nLQ@B}|2(*|akFu=bMWx6zOPg>vcKd#5+Em~ELkIN6#Rbx9sm_8 literal 0 HcmV?d00001 diff --git a/test/oaassist/EtOAAssist/icon/w_SaveAs.png b/test/oaassist/EtOAAssist/icon/w_SaveAs.png new file mode 100644 index 0000000000000000000000000000000000000000..a5fe456f5f79799d24e7d2b894dce9964ca1d6f0 GIT binary patch literal 14246 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 M(kfEb5~iR352)qN@c;k- literal 0 HcmV?d00001 diff --git a/test/oaassist/EtOAAssist/index.html b/test/oaassist/EtOAAssist/index.html new file mode 100644 index 0000000..095b758 --- /dev/null +++ b/test/oaassist/EtOAAssist/index.html @@ -0,0 +1,5 @@ + + + + + diff --git a/test/oaassist/EtOAAssist/js/common/common.js b/test/oaassist/EtOAAssist/js/common/common.js new file mode 100644 index 0000000..7a13c95 --- /dev/null +++ b/test/oaassist/EtOAAssist/js/common/common.js @@ -0,0 +1,229 @@ +// -------------------------- 通用方法 --------------------------- +//扩展js string endwith,startwith方法 +String.prototype.endWith = function (str) { + if (str == null || str == "" || this.length == 0 || str.length > this.length) + return false; + if (this.substring(this.length - str.length) == str) + return true; + else + return false; +} + +String.prototype.startWith = function (str) { + if (str == null || str == "" || this.length == 0 || str.length > this.length) + return false; + if (this.substr(0, str.length) == str) + return true; + else + return false; +} + +//UTF-16转UTF-8 +function utf16ToUtf8(s) { + if (!s) { + return; + } + var i, code, ret = [], + len = s.length; + for (i = 0; i < len; i++) { + code = s.charCodeAt(i); + if (code > 0x0 && code <= 0x7f) { + //单字节 + //UTF-16 0000 - 007F + //UTF-8 0xxxxxxx + ret.push(s.charAt(i)); + } else if (code >= 0x80 && code <= 0x7ff) { + //双字节 + //UTF-16 0080 - 07FF + //UTF-8 110xxxxx 10xxxxxx + ret.push( + //110xxxxx + String.fromCharCode(0xc0 | ((code >> 6) & 0x1f)), + //10xxxxxx + String.fromCharCode(0x80 | (code & 0x3f)) + ); + } else if (code >= 0x800 && code <= 0xffff) { + //三字节 + //UTF-16 0800 - FFFF + //UTF-8 1110xxxx 10xxxxxx 10xxxxxx + ret.push( + //1110xxxx + String.fromCharCode(0xe0 | ((code >> 12) & 0xf)), + //10xxxxxx + String.fromCharCode(0x80 | ((code >> 6) & 0x3f)), + //10xxxxxx + String.fromCharCode(0x80 | (code & 0x3f)) + ); + } + } + return ret.join(''); +} + +//若要显示:当前日期加时间(如:200906121200) +function currentTime() { + var now = new Date(); + + var year = now.getFullYear(); //年 + var month = now.getMonth() + 1; //月 + var day = now.getDate(); //日 + + var hh = now.getHours(); //时 + var mm = now.getMinutes(); //分 + + var clock = year + ""; + + if (month < 10) + clock += "0"; + + clock += month + ""; + + if (day < 10) + clock += "0"; + + clock += day + ""; + + if (hh < 10) + clock += "0"; + + clock += hh + ""; + if (mm < 10) clock += '0'; + clock += mm; + return (clock); +} + +/** + * 判断文件个数是否为0,若为0则关闭 + * @param {*} name + */ +function closeEtIfNoDocument() { + var etApp = wps.EtApplication(); + var docs = etApp.Workbooks; + if (docs && docs.Count == 0) { + etApp.Quit(); + } +} + +function activeTab() { + wps.ribbonUI.ActivateTab('WPSWorkExtTab'); +} + +function showOATab() { + wps.PluginStorage.setItem("ShowOATabDocActive", pCheckIfOADoc()); //根据文件是否为OA文件来显示OA菜单 + wps.ribbonUI.Invalidate(); // 刷新Ribbon自定义按钮的状态 +} + +function pGetParamName(data, attr) { + var start = data.indexOf(attr); + data = data.substring(start + attr.length); + return data; +} + +/** + * 从requst中获取文件名(确保请求中有filename这个参数) + * @param {*} request + * @param {*} url + */ + function pGetFileName(request, url) { + var disposition = request.getResponseHeader("Content-Disposition"); + var filename = ""; + if (disposition) { + var matchs = pGetParamName(disposition, "filename="); + if (matchs) { + filename = decodeURIComponent(matchs); + } else { + filename = "petro" + Date.getTime(); + } + } else { + filename = url.substring(url.lastIndexOf("/") + 1); + filename=filename.split("?")[0] + } + return filename; +} + +function StringToUint8Array(string) { + var binLen, buffer, chars, i, _i; + binLen = string.length; + buffer = new ArrayBuffer(binLen); + chars = new Uint8Array(buffer); + for (var i = 0; i < binLen; ++i) { + chars[i] = String.prototype.charCodeAt.call(string, i); + } + return buffer; +} + +function DownloadFile(url, callback) { + // 需要根据业务实现一套 + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (this.readyState == 4 && this.status == 200) { + var path = wps.Env.GetTempPath() + "/" + pGetFileName(xhr, url); + var reader = new FileReader(); + reader.onload = function () { + wps.FileSystem.writeAsBinaryString(path, reader.result); + callback(path); + }; + reader.readAsBinaryString(xhr.response); + } + } + xhr.open('GET', url); + xhr.responseType = 'blob'; + xhr.send(); +} + +function UploadFile(strFileName, strPath, uploadPath, strFieldName, OnSuccess, OnFail) { + var xhr = new XMLHttpRequest(); + xhr.open('POST', uploadPath); + + function KFormData() { + this.fake = true; + this.boundary = "--------FormData" + Math.random(); + this._fields = []; + } + KFormData.prototype.append = function (key, value) { + this._fields.push([key, value]); + } + KFormData.prototype.toString = function () { + var boundary = this.boundary; + var body = ""; + this._fields.forEach(function (field) { + body += "--" + boundary + "\r\n"; + if (field[1].name) { + var file = field[1]; + body += "Content-Disposition: form-data; name=\"" + field[0] + "\"; filename=\"" + file.name + "\"\r\n"; + body += "Content-Type: " + file.type + "\r\n\r\n"; + body += file.getAsBinary() + "\r\n"; + } else { + body += "Content-Disposition: form-data; name=\"" + field[0] + "\";\r\n\r\n"; + body += field[1] + "\r\n"; + } + }); + body += "--" + boundary + "--"; + return body; + } + var fileData = wps.FileSystem.readAsBinaryString(strPath); + var data = new KFormData(); + data.append('file', { + name: strFileName, + type: "application/octet-stream", + getAsBinary: function () { + return fileData; + } + }); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + if (xhr.status == 200) + OnSuccess(xhr.response) + else + OnFail(xhr.response); + } + }; + xhr.setRequestHeader("Cache-Control", "no-cache"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + if (data.fake) { + xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + data.boundary); + var arr = StringToUint8Array(data.toString()); + xhr.send(arr); + } else { + xhr.send(data); + } +} \ No newline at end of file diff --git a/test/oaassist/EtOAAssist/js/common/func_docEvents.js b/test/oaassist/EtOAAssist/js/common/func_docEvents.js new file mode 100644 index 0000000..e8cb455 --- /dev/null +++ b/test/oaassist/EtOAAssist/js/common/func_docEvents.js @@ -0,0 +1,251 @@ +// 打印前监听事件 +function OnWorkbookBeforePrint(doc) { + return; +} + + +//切换窗口时触发的事件 +function OnWindowActivate() { + console.log("OnWindowActivate" + "======================="); + + var l_doc = wps.EtApplication().ActiveWorkbook; + SetCurrDocEnvProp(l_doc); // 设置当前文档对应的用户名 + showOATab(); // 根据文件是否为OA文件来显示OA菜单再进行刷新按钮 + setTimeout(activeTab, 2000); // 激活页面必须要页签显示出来,所以做1秒延迟 + return; +} + +/** + * 作用:判断OA文档是否被另存为了 + */ +function CheckIfOADocSaveAs(doc) { + if (!doc) { + return; + } + // 获取OA文档的原始保存路径 + var l_Path = GetDocParamsValue(doc, "SourcePath"); + // 原路径和当前文件的路径对比 + return l_Path == doc.FullName; +} + + +// 当文件保存前触发的事件 +function OnWorkbookBeforeSave(doc) { + console.log("OnWorkbookBeforeSave"); + + //设置变量,判断是否当前用户按了自定义的OA文件保存按钮 + var l_IsOADocButtonSave = false; + l_IsOADocButtonSave = wps.PluginStorage.getItem("OADocUserSave"); + + //根据传入参数判断当前文档是否能另存为,默认不能另存为 + if (pCheckCurrOADocCanSaveAs(doc) == false) { //先根据OA助手的默认设置判断是否允许OA文档另存为操作 + //如果配置文件:OA文档不允许另存为,则再判断 + //2、判断当前OA文档是否不落地文档 + if (pIsOnlineOADoc(doc) == true) { + //如果是不落地文档,则判断是否是系统正在保存 + if (l_IsOADocButtonSave == false) { + alert("来自OA的不落地文档,禁止另存为本地文档!"); + //如果是OA文档,则禁止另存为 + wps.ApiEvent.Cancel = true; + } + } else { + //这里要再判断OA文档是否被用户另存为 + if (l_IsOADocButtonSave == false) { + doc.Save(); //直接保存本地就行 + //如果是OA文档,则禁止另存为 + wps.ApiEvent.Cancel = true; + } else {} + } + + } + + //保存文档后,也要刷新一下Ribbon按钮的状态 + showOATab(); + return; +} + + +//文档保存前关闭事件 +/** + * 作用: + * @param {*} doc + */ +function OnWorkbookBeforeClose(doc) { + console.log('OnWorkbookBeforeClose'); + + var l_fullName = doc.FullName; + var l_bIsOADoc = false; + l_bIsOADoc = CheckIfDocIsOADoc(doc); //判断是否OA文档要关闭 + if (l_bIsOADoc == false) { // 非OA文档不做处理 + return; + } + //判断是否只读的文档,或受保护的文档,对于只读的文档,不给予保存提示 + if (pISOADocReadOnly(doc) == false) { + if (doc.Saved == false) { //如果OA文档关闭前,有未保存的数据 + if (wps.confirm("系统文件有改动,是否提交后关闭?" + "\n" + "确认后请按上传按钮执行上传操作。取消则继续关闭文档。")) { + wps.ApiEvent.Cancel = true; + return; + } + } + } + doc.Close(false); //保存待定的更改。 + closeEtIfNoDocument(); // 判断文件个数是否为0,若为0则关闭组件 + wps.FileSystem.Remove(l_fullName); +} + + +//文档保存后关闭事件 +function OnWorkbookAfterClose(doc) { + console.log("OnWorkbookAfterClose"); + + var l_NofityURL = GetDocParamsValue(doc, "notifyUrl"); + if (l_NofityURL) { + l_NofityURL = l_NofityURL.replace("{?}", "3"); //约定:参数为3则文档关闭 + console.log("" + l_NofityURL); + NotifyToServer(l_NofityURL); + } + + pRemoveDocParam(doc); // 关闭文档时,移除PluginStorage对象的参数 + pSetetAppUserName(); // 判断文档关闭后,如果系统已经没有打开的文档了,则设置回初始用户名 +} + +//文档打开事件 +function OnWorkbookOpen(doc) { + //设置当前新增文档是否来自OA的文档 + // if (wps.PluginStorage.getItem("IsInCurrOADocOpen") == false) { + // //如果是用户自己在WPS环境打开文档,则设置非OA文档标识 + // pSetNoneOADocFlag(doc); + // } + + OnWindowActivate(); + ChangeOATabOnDocOpen(); //打开文档后,默认打开Tab页 +} + +//新建文档事件 +function OnWorkbookNew(doc) { + //设置当前新增文档是否来自OA的文档 + // if (wps.PluginStorage.getItem("IsInCurrOADocOpen") == false) { + // //如果是用户自己在WPS环境打开文档,则设置非OA文档标识 + // pSetNoneOADocFlag(doc); + // } + ChangeOATabOnDocOpen(); // 打开OA助手Tab菜单页 + wps.ribbonUI.Invalidate(); // 刷新Ribbon按钮的状态 +} + + +/** + * 作用:判断当前文档是否是只读文档 + * 返回值:布尔 + */ +function pISOADocReadOnly(doc) { + if (!doc) { + return false; + } + var l_openType = GetDocParamsValue(doc, "openType"); // 获取OA传入的参数 openType + if (l_openType == "") { + return false; + } + try { + if (!!l_openType.protectType) { + return true; + } // 保护 + } catch (err) { + return false; + } +} + + +/** + * 作用:根据当前活动文档的情况判断,当前文档适用的系统参数,例如:当前文档对应的用户名称等 + */ +function SetCurrDocEnvProp(doc) { + if (!doc) return; + var l_bIsOADoc = false; + l_bIsOADoc = pCheckIfOADoc(doc); + + //如果是OA文件,则按OA传来的用户名设置WPS OA助手WPS用户名设置按钮冲突 + if (l_bIsOADoc == true) { + var l_userName = GetDocParamsValue(doc, "userName"); + if (l_userName != "") { + wps.EtApplication().UserName = l_userName; + return; + } + } + //如果是非OA文件或者参数的值是空值,则按WPS安装默认用户名设置 + wps.EtApplication().UserName = wps.PluginStorage.getItem("WPSInitUserName"); +} + +/* + 入口参数:doc + 功能说明:判断当前文档是否能另存为本地文件 + 返回值:布尔值true or false +*/ +function pCheckCurrOADocCanSaveAs(doc) { + //如果是非OA文档,则允许另存为 + if (CheckIfDocIsOADoc(doc) == false) return true; + + //对于来自OA系统的文档,则获取该文档对应的属性参数 + var l_CanSaveAs = GetDocParamsValue(doc, "CanSaveAs"); + + //判断OA传入的参数 + if (typeof (l_CanSaveAs) == "boolean") { + return l_CanSaveAs; + } + return false; +} + +/** + * 作用:判断文档关闭后,如果系统已经没有打开的文档了,则设置回初始用户名 + */ +function pSetetAppUserName() { + //文档全部关闭的情况下,把WPS初始启动的用户名设置回去 + if (wps.EtApplication().Workbooks.Count == 1) { + var l_strUserName = wps.PluginStorage.getItem("WPSInitUserName"); + wps.EtApplication().UserName = l_strUserName; + } +} + +/** + * 作用:文档关闭后,删除对应的PluginStorage内的参数信息 + * 返回值:没有返回值 + * @param {*} doc + */ +function pRemoveDocParam(doc) { + if (!doc) return; + wps.PluginStorage.removeItem(doc.FullName); + return; +} + +/** + * 作用:判断当前文档是否从OA来的文档,如果非OA文档(就是本地新建或打开的文档,则设置EnumOAFlag 标识) + * 作用:设置非OA文档的标识状态 + * @param {*} doc + * 返回值:无 + */ +function pSetNoneOADocFlag(doc) { + if (!doc) return; + var l_param = wps.PluginStorage.getItem(doc.FullName); //定义JSON文档参数 + var l_objParams = new Object(); + if (l_param) { + l_objParams = JSON.parse(l_param); + } + l_objParams.isOA = EnumOAFlag.DocFromNoOA; // 新增非OA打开文档属性 + wps.PluginStorage.setItem(doc.FullName, JSON.stringify(l_objParams)); // 存入内存中 +} + + +/** + * 作用:根据设置判断打开文件是否默认激活OA助手工具Tab菜单 + * 返回值:无 + */ +function ChangeOATabOnDocOpen() { + var l_ShowOATab = true; //默认打开 + l_ShowOATab = wps.PluginStorage.getItem("ShowOATabDocActive"); + + if (l_ShowOATab == true) { + if (wps.ribbonUI) + wps.ribbonUI.ActivateTab("WPSWorkExtTab"); //新建文档时,自动切换到OA助手状态 + else + wps.ActivateTab("WPSWorkExtTab"); //新建文档时,自动切换到OA助手状态 + } +} \ No newline at end of file diff --git a/test/oaassist/EtOAAssist/js/common/func_docProcess.js b/test/oaassist/EtOAAssist/js/common/func_docProcess.js new file mode 100644 index 0000000..f7a77bc --- /dev/null +++ b/test/oaassist/EtOAAssist/js/common/func_docProcess.js @@ -0,0 +1,354 @@ +/** + * 从OA调用传来的指令,打开本地新建文件 + * @param {*} fileUrl 文件url路径 + */ +function NewFile(params) { + //获取ET Application 对象 + var etApp = wps.EtApplication(); + wps.PluginStorage.setItem("IsInCurrOADocOpen", true); //设置OA打开文档的临时状态 + var doc = etApp.Workbooks.Add(); //新增OA端文档 + wps.PluginStorage.setItem("IsInCurrOADocOpen", false); + + //检查系统临时文件目录是否能访问 + if (wps.Env && wps.Env.GetTempPath) { + if (params.newFileName) { + //按OA传入的文件名称保存 + doc.SaveAs($FileName = wps.Env.GetTempPath() + "/" + params.newFileName, undefined, undefined, undefined, undefined, undefined, undefined, undefined, false); + } else { + //OA传入空文件名称,则保存成系统时间文件 + doc.SaveAs($FileName = wps.Env.GetTempPath() + "/OA_" + currentTime(), undefined, undefined, undefined, undefined, undefined, undefined, undefined, false); + } + } else { + alert("文档保存临时目录出错!不能保存新建文档!请联系系统开发商。"); + } + + var l_NofityURL = GetParamsValue(params, "notifyUrl"); + if (l_NofityURL) { + NotifyToServer(l_NofityURL.replace("{?}", "1")); + } + + //Office文件打开后,设置该文件属性:从服务端来的OA文件 + pSetOADocumentFlag(doc, params); + //设置当前文档为 本地磁盘落地模式 + DoSetOADocLandMode(doc, EnumDocLandMode.DLM_LocalDoc); + //强制执行一次Activate事件 + OnWindowActivate(); + + return doc; //返回新创建的Document对象 +} + + +/** + * 打开服务器上的文件 + * @param {*} fileUrl 文件url路径 + */ +function OpenFile(params) { + var l_strFileUrl = params.fileName; //来自OA网页端的OA文件下载路径 + var doc; + var l_IsOnlineDoc = false; //默认打开的是不落地文档 + if (l_strFileUrl) { + //下载文档之前,判断是否已下载该文件 + if (pCheckIsExistOpenOADoc(l_strFileUrl) == true) { + //如果找到相同OA地址文档,则给予提示 + wps.EtApplication().Visible = true + //根据OA助手对是否允许再次打开相同文件的判断处理 + var l_AllowOADocReOpen = false; + l_AllowOADocReOpen = wps.PluginStorage.getItem("AllowOADocReOpen"); + if (l_AllowOADocReOpen == false) { + alert("已打开相同的OA文件,请关闭之前的文件,再次打开。"); + wps.EtApplication().Visible = true + return null; + } else { + //处理重复打开相同OA 文件的方法 + var nDocCount = wps.EtApplication().Workbooks.Count; + pReOpenOADoc(l_strFileUrl); + //重复打开的文档采用不落地的方式打开 + // 不落地方式打开文档判断落地比较多,V1版本先暂时关闭 + l_IsOnlineDoc = true; + var nDocCount_New = wps.EtApplication().Workbooks.Count; + if (nDocCount_New > nDocCount) { + doc = wps.EtApplication().ActiveWorkbook; + } + } + } else { + //如果当前没有打开文档,则另存为本地文件,再打开 + if (l_strFileUrl.startWith("http")) { // 网络文档 + DownloadFile(l_strFileUrl, function (path) { + if (path == "") { + alert("从服务端下载路径:" + l_strFileUrl + "\n" + "获取文件下载失败!"); + return null; + } + + doc = pDoOpenOADocProcess(params, path); + pOpenFile(doc, params, l_IsOnlineDoc); + }); + return null; + } else { //本地文档 + doc = pDoOpenOADocProcess(params, l_strFileUrl); + if (doc) + doc.SaveAs($FileName = wps.Env.GetTempPath() + "/" + doc.Name, undefined, undefined, undefined, undefined, undefined, undefined, undefined, false); + } + } + } else { + //fileURL 如果为空,则按新建OA本地文件处理 + NewFile(params); + } + + //如果打开pdf等其他非Office文档,则doc对象为空 + if (!doc) { + return null; + } + + pOpenFile(doc, params, l_IsOnlineDoc); + + return doc +} + +function pOpenFile(doc, params, isOnlineDoc) { + var l_IsOnlineDoc = isOnlineDoc + console.log(doc) + //Office文件打开后,设置该文件属性:从服务端来的OA文件 + pSetOADocumentFlag(doc, params); + //设置当前文档为 本地磁盘落地模式 + if (l_IsOnlineDoc == true) { + DoSetOADocLandMode(doc, EnumDocLandMode.DLM_OnlineDoc); + } else { + DoSetOADocLandMode(doc, EnumDocLandMode.DLM_LocalDoc); + } + + l_NofityURL = GetParamsValue(params, "notifyUrl"); + if (l_NofityURL) { + l_NofityURL = l_NofityURL.replace("{?}", "1"); //约定:参数为1则代码打开状态 + NotifyToServer(l_NofityURL); + } + //重新设置工具条按钮的显示状态 + pDoResetRibbonGroups(); + // 触发切换窗口事件 + OnWindowActivate(); + return doc; +} + +/** + * 文档打开服务器上的文件 + * @param {*} fileUrl 文件url路径 + */ +function OpenOnLineFile(OAParams) { + //OA参数如果为空的话退出 + if (!OAParams) return; + + //获取在线文档URL + var l_OAFileUrl = OAParams.fileName; + var l_doc; + if (l_OAFileUrl) { + //下载文档不落地(16版WPS的925后支持) + wps.PluginStorage.setItem("IsInCurrOADocOpen", true); + wps.EtApplication().Workbooks.OpenFromUrl(l_OAFileUrl, "OnOpenOnLineDocSuccess", "OnOpenOnLineDocDownFail"); + wps.PluginStorage.setItem("IsInCurrOADocOpen", false); + l_doc = wps.EtApplication().ActiveWorkbook; + } + + //Office文件打开后,设置该文件属性:从服务端来的OA文件 + pOpenFile(l_doc, OAParams, true); + return l_doc; +} + + +/** + * 打开在线文档成功后触发事件 + * @param {*} resp + */ +function OnOpenOnLineDocSuccess(resp) { + +} + + +/** + * 作用:打开文档处理的各种过程,包含:打开带密码的文档,保护方式打开文档,修订方式打开文档等种种情况 + * params Object OA Web端传来的请求JSON字符串,具体参数说明看下面数据 + * TempLocalFile : 字符串 先把文档从OA系统下载并保存在Temp临时目录,这个参数指已经下载下来的本地文档地址 + * ----------------------以下是OA参数的一些具体规范名称 + * docId String 文档ID + * uploadPath String 保存文档接口 + * fileName String 获取服务器文档接口(不传即为新建空文档) + * userName String 用于更改显示修改人的用户名 + * buttonGroups string 自定义按钮组 (可不传,不传显示所有按钮) + * openType String 文档打开方式 ,不传正常打开 + * protectType bool 文档保护类型,false或是未定义为不启用保护,其他为启用 + * password String密码 + */ +function pDoOpenOADocProcess(params, TempLocalFile) { + var l_ProtectType = false; //默认文档保护类型 0 为不启用保护 + var l_ProtectPassword = ""; //默认文档密码为空 + + var l_strDocPassword = ""; //打开文档密码参数 + + for (var key = "" in params) { + switch (key.toUpperCase()) // + { + case "userName".toUpperCase(): //修改当前文档用户名 + wps.EtApplication().UserName = params[key]; + break; + case "openType".toUpperCase(): + l_ProtectType = params[key].protectType; //获取OA传来的文档保护类型 + l_ProtectPassword = params[key].password; //获取OA传来的保护模式下的文档密码 + break; + case "buttonGroups".toUpperCase(): //按钮组合 + break; + case "docPassword".toUpperCase(): //传入打开文件的密码 + l_strDocPassword = params[key].docPassword; + break; + } + + } + + var l_Doc; + l_Doc = wps.EtApplication().Workbooks.Open(TempLocalFile, false, false, undefined, l_strDocPassword); + + //打开文档后,根据保护类型设置文档保护 + if (!!l_ProtectType) // 设置文档保护 + SetOADocProtect(l_Doc, l_ProtectPassword); + return l_Doc; +} + +/** + * protectType: '', 文档保护模式 + * @param {*} ProtectPassword + * @param {*} doc + */ +function SetOADocProtect(doc, ProtectPassword) { + if (!doc) return; //校验文档是否存在 + + // 保护文档如果之前有被保护,再次保护会出问题,需要先解除保护 + doc.Unprotect(); + doc.Protect(ProtectPassword); + return; +} + + +/** + * 打开在线不落地文档出现失败时,给予错误提示 + */ +function OnOpenOnLineDocDownFail() { + alert("打开在线不落地文档失败!请尝试重新打开。"); + return; +} + +/** + * 功能说明:判断是否已存在来自OA的已打开的文档 + * @param {字符串} FileURL + */ +function pCheckIsExistOpenOADoc(FileURL) { + var l_DocCount = wps.EtApplication().Workbooks.Count; + if (l_DocCount <= 0) return false; + + //轮询检查当前已打开的WPS文档中,是否存在OA相同的文件 + if (l_DocCount >= 1) { + for (var l_index = 1; l_index <= l_DocCount; l_index++) { + var l_objDoc = wps.EtApplication().Workbooks.Item(l_index); + + var l_strParam = wps.PluginStorage.getItem(l_objDoc.FullName); + if (l_strParam == null) + continue; + var l_objParam = JSON.parse(l_strParam) + if (l_objParam.fileName == FileURL) { + return true; + } + } + return false; + } +} + +/** + * 参数: + * doc : 当前OA文档的Document对象 + * DocLandMode : 落地模式设置 + */ +function DoSetOADocLandMode(doc, DocLandMode) { + if (!doc) return; + var l_Param = wps.PluginStorage.getItem(doc.FullName); + var l_objParam = JSON.parse(l_Param); + //增加属性,或设置 + l_objParam.OADocLandMode = DocLandMode; //设置OA文档的落地标志 + + var l_p = JSON.stringify(l_objParam); + //将OA文档落地模式标志存入系统变量对象保存 + + wps.PluginStorage.setItem(doc.FullName, l_p); + +} + +//Office文件打开后,设置该文件属性:从服务端来的OA文件 +function pSetOADocumentFlag(doc, params) { + if (!doc) { + return; + } + var l_Param = params; + l_Param.isOA = EnumOAFlag.DocFromOA; //设置OA打开文档的标志 + l_Param.SourcePath = doc.FullName; //保存OA的原始文件路径,用于保存时分析,是否进行了另存为操作 + + if (doc) { + var l_p = JSON.stringify(l_Param); + + //将OA文档标志存入系统变量对象保存 + wps.PluginStorage.setItem(doc.FullName, l_p); + } +} + +/** + * 作用:设置Ribbon工具条的按钮显示状态 + * @param {*} paramsGroups + */ +function pDoResetRibbonGroups(paramsGroups) { + +} + +/** + * 按照定时器的时间,自动执行所有文档的自动保存事件 + */ +function OnDocSaveByAutoTimer() { + var l_Doc; + + var l_Count = 0 + var l_docCounts = wps.EtApplication().Workbooks.Count; + for (l_Count = 0; l_Count < l_docCounts; l_Count++) { + l_Doc = wps.EtApplication().Workbooks.Item(l_Count); + if (l_Doc) { + if (pCheckIfOADoc(l_Doc) == true) { // 是否为OA文件 + if (pISOADocReadOnly(l_Doc) == false) { // 是否为只读文档 + //执行自动上传到OA服务器端的操作 + pAutoUploadToServer(l_Doc); + //保存该文档对应的访问过程记录信息 + } + } + } + } +} + +/** + * 实现一个定时器 + */ +function OpenTimerRun(funcCallBack) { + var l_mCount = 0; //设置一个计时器,按每分钟执行一次; 10分钟后重复执行 + var l_timeID = 0; //用于保存计时器ID值 + + // 对间隔时间做处理 + var l_AutoSaveToServerTime = wps.PluginStorage.getItem("AutoSaveToServerTime"); + if (l_AutoSaveToServerTime == 0) { // 设置为0则不启动定时器 + l_timeID = wps.PluginStorage.getItem("TempTimerID"); + clearInterval(l_timeID); + return; + } else if (l_AutoSaveToServerTime < 3) { + l_AutoSaveToServerTime = 3; + } + + l_timeID = setInterval(function () { + l_mCount = l_mCount + 1; + if (l_mCount > l_AutoSaveToServerTime) { //l_AutoSaveToServerTime 值由系统配置时设定,见pInitParameters()函数 + l_mCount = 0; + funcCallBack(); //每隔l_AutoSaveToServerTime 分钟(例如10分钟)执行一次回调函数 + } + }, 60000); //60000 每隔1分钟,执行一次操作(1000*60) + + + wps.PluginStorage.setItem("TempTimerID", l_timeID); //保存计时器ID值 +} \ No newline at end of file diff --git a/test/oaassist/EtOAAssist/js/common/func_oastarter.js b/test/oaassist/EtOAAssist/js/common/func_oastarter.js new file mode 100644 index 0000000..4ee7117 --- /dev/null +++ b/test/oaassist/EtOAAssist/js/common/func_oastarter.js @@ -0,0 +1,56 @@ +/** + * web页面调用WPS加载项的方法入口 + * * info参数结构 + * info:[ + * { + * '方法名':'方法参数',需要执行的方法 + * }, + * ... + * ] + * @param {*} info + */ +function dispatcher(info) { + var funcs = info.funcs; + //NotifyToWeb(); + //alert(JSON.stringify(funcs)); + //执行web页面传递的方法 + for (var index = 0; index < funcs.length; index++) { + var func = funcs[index]; + for (var key in func) { + func[key].isOA=true + if (key === "OpenDoc") { // OpenDoc 属于普通的打开文档的操作方式,文档落地操作 + OpenDoc(func[key]); //进入打开文档处理函数 + } else if (key === "OnlineEditDoc") { //在线方式打开文档,属于文档不落地的方式打开 + OnlineEditDoc(func[key]); + } else if (key === "NewDoc") { + OpenDoc(func[key]); + } + } + } + return {message:"ok", app:wps.Application.Name} +} + +/** + * + * @param {*} params OA端传入的参数 + */ +function OnlineEditDoc(OaParams) { + //如果 + if (OaParams.fileName == "") { + NewFile(OaParams); + } else { + //OA传来下载文件的URL地址,调用openFile 方法打开 + OpenOnLineFile(OaParams); + } +} + +///打开来自OA端传递来的文档 +function OpenDoc(OaParams) { + //如果 + if (OaParams.fileName == "") { + NewFile(OaParams); + } else { + //OA传来下载文件的URL地址,调用openFile 方法打开 + OpenFile(OaParams); + } +} \ No newline at end of file diff --git a/test/oaassist/EtOAAssist/js/common/func_tabcontrol.js b/test/oaassist/EtOAAssist/js/common/func_tabcontrol.js new file mode 100644 index 0000000..e0fde6d --- /dev/null +++ b/test/oaassist/EtOAAssist/js/common/func_tabcontrol.js @@ -0,0 +1,441 @@ +var EnumOAFlag = { + DocFromOA: 1, + DocFromNoOA: 0 +} + +//记录是否用户点击OA文件的保存按钮 +var EnumDocSaveFlag = { + OADocSave: 1, + NoneOADocSave: 0 +} + +//标识文档的落地模式 本地文档落地 0 ,不落地 1 +var EnumDocLandMode = { + DLM_LocalDoc: 0, + DLM_OnlineDoc: 1 +} + +//加载时会执行的方法 +function OnWPSWorkTabLoad(ribbonUI) { + wps.ribbonUI = ribbonUI; + + OnJSWorkInit(); //初始化文档事件(全局参数,挂载监听事件) + activeTab(); // 激活OA助手菜单 + OpenTimerRun(OnDocSaveByAutoTimer); //启动定时备份过程 + return true; +} + +//文档各类初始化工作(WPS Js环境) +function OnJSWorkInit() { + pInitParameters(); //OA助手环境的所有配置控制的初始化过程 + AddWorkbookEvent(); //挂接文档事件处理函数 +} + + +//初始化全局参数 +function pInitParameters() { + wps.PluginStorage.setItem("OADocUserSave", EnumDocSaveFlag.NoneOADocSave); //初始化,没有用户点击保存按钮 + + var l_wpsUserName = wps.EtApplication().UserName; + wps.PluginStorage.setItem("WPSInitUserName", l_wpsUserName); //在OA助手加载前,先保存用户原有的WPS应用用户名称 + + wps.PluginStorage.setItem("OADocCanSaveAs", false); //默认OA文档不能另存为本地 + wps.PluginStorage.setItem("AllowOADocReOpen", false); //设置是否允许来自OA的文件再次被打开 + wps.PluginStorage.setItem("ShowOATabDocActive", false); //设置新打开文档是否默认显示OA助手菜单Tab //默认为false + + wps.PluginStorage.setItem("DefaultUploadFieldName", "file"); //针对UploadFile方法设置上载字段名称 + + wps.PluginStorage.setItem("AutoSaveToServerTime", "10"); //自动保存回OA服务端的时间间隔。如果设置0,则关闭,最小设置3分钟 + wps.PluginStorage.setItem("TempTimerID", "0"); //临时值,用于保存计时器ID的临时值 + + // 以下是一些临时状态参数,用于打开文档等的状态判断 + wps.PluginStorage.setItem("IsInCurrOADocOpen", false); //用于执行来自OA端的新建或打开文档时的状态 + wps.PluginStorage.setItem("IsInCurrOADocSaveAs", false); //用于执行来自OA端的文档另存为本地的状态 +} + +//挂载WPS的表格事件 +function AddWorkbookEvent() { + wps.ApiEvent.AddApiEventListener("WindowActivate", OnWindowActivate); + wps.ApiEvent.AddApiEventListener("WorkbookBeforeClose", OnWorkbookBeforeClose); + wps.ApiEvent.AddApiEventListener("WorkbookBeforeSave", OnWorkbookBeforeSave); + wps.ApiEvent.AddApiEventListener("WorkbookOpen", OnWorkbookOpen); + wps.ApiEvent.AddApiEventListener("NewWorkbook", OnWorkbookNew); + console.log("AddWorkbookEvent"); +} + +/** + * 根据传入Document对象,获取OA传入的参数的某个Key值的Value + * @param {*} Doc + * @param {*} Key + * 返回值:返回指定 Key的 Value + */ +function GetDocParamsValue(Doc, Key) { + if (!Doc) { + return ""; + } + + var l_Params = wps.PluginStorage.getItem(Doc.FullName); + if (!l_Params) { + return ""; + } + + var l_objParams = JSON.parse(l_Params); + if (typeof (l_objParams) == "undefined") { + return ""; + } + + var l_rtnValue = l_objParams[Key]; + if (typeof (l_rtnValue) == "undefined" || l_rtnValue == null) { + return ""; + } + return l_rtnValue; +} + +/** + * 作用:根据OA传入参数,设置是否显示Ribbob按钮组 + * 参数:CtrlID 是OnGetVisible 传入的Ribbob控件的ID值 + */ +function pShowRibbonGroupByOADocParam(CtrlID) { + var l_Doc = wps.EtApplication().ActiveWorkbook; + if (!l_Doc) { + return false; //如果未装入文档,则设置OA助手按钮组不可见 + } + + //获取OA传入的按钮组参数组 + var l_grpButtonParams = GetDocParamsValue(l_Doc, "buttonGroups"); //disableBtns + l_grpButtonParams = l_grpButtonParams + "," + GetDocParamsValue(l_Doc, "disableBtns"); + // 要求OA传入控制自定义按钮显示的参数为字符串 中间用 , 分隔开 + if (typeof (l_grpButtonParams) == "string") { + var l_arrayGroup = new Array(); + l_arrayGroup = l_grpButtonParams.split(","); + //console.log(l_grpButtonParams); + + // 判断当前按钮是否存在于数组 + if (l_arrayGroup.indexOf(CtrlID) >= 0) { + return false; + } + } + // 添加OA菜单判断 + if (CtrlID == "WPSWorkExtTab") { + var l_value = wps.PluginStorage.getItem("ShowOATabDocActive"); + wps.PluginStorage.setItem("ShowOATabDocActive", false); //初始化临时状态变量 + console.log("菜单:" + l_value); + return l_value; + } + + //disableBtns + + return true; +} + +/** + * 调用文件上传到OA服务端时, + * @param {*} resp + * wdDoNotSaveChanges 0 *不保存待定的更改。 + * wdPromptToSaveChanges -2 *提示用户保存待定更改。 + * wdSaveChanges -1 *自动保存待定更改,而不提示用户。 + */ +function OnUploadToServerSuccess(resp) { + var l_doc = wps.EtApplication().ActiveWorkbook; + if (wps.confirm("文件上传成功!继续编辑请确认,取消关闭文档。") == false) { + if (l_doc) { + console.log("OnUploadToServerSuccess: before Close"); + l_doc.Close(-1); //保存文档后关闭 + console.log("OnUploadToServerSuccess: after Close"); + } + } + + var l_NofityURL = GetDocParamsValue(l_doc, "notifyUrl"); + if (l_NofityURL != "") { + l_NofityURL = l_NofityURL.replace("{?}", "2"); //约定:参数为2则文档被成功上传 + NotifyToServer(l_NofityURL); + } +} + +function OnUploadToServerFail(resp) { + alert("文件上传失败!"); +} + +//判断当前文档是否是OA文档 +function pCheckIfOADoc() { + var doc = wps.EtApplication().ActiveWorkbook; + if (!doc) + return false; + return CheckIfDocIsOADoc(doc); +} + +//根据传入的doc对象,判断当前文档是否是OA文档 +function CheckIfDocIsOADoc(doc) { + if (!doc) { + return false; + } + var l_isOA = GetDocParamsValue(doc, "isOA"); + if (l_isOA == "") { + return false + }; + return l_isOA == EnumOAFlag.DocFromOA ? true : false; +} + +//返回是否可以点击OA保存按钮的状态 +function OnSetSaveToOAEnable() { + return pCheckIfOADoc(); +} + +/** + * 作用:判断是否是不落地文档 + * 参数:doc 文档对象 + * 返回值: 布尔值 + */ +function pIsOnlineOADoc(doc) { + var l_LandMode = GetDocParamsValue(doc, "OADocLandMode"); //获取文档落地模式 + if (l_LandMode == "") { //用户本地打开的文档 + return false; + } + return l_LandMode == EnumDocLandMode.DLM_OnlineDoc; +} + +//保存到OA后台服务器 +function OnBtnSaveToServer() { + // console.log('SaveToServer'); + var l_doc = wps.EtApplication().ActiveWorkbook; + if (!l_doc) { + alert("空文档不能保存!"); + return; + } + + //非OA文档,不能上传到OA + if (pCheckIfOADoc() == false) { + alert("非系统打开的文档,不能直接上传到系统!"); + return; + } + + //如果是OA打开的文档,并且设置了保护的文档,则不能再上传到OA服务器 + if (pISOADocReadOnly(l_doc)) { + wps.alert("系统设置了保护的文档,不能再提交到系统后台。"); + return; + } + + /** + * 参数定义:OAAsist.UploadFile(name, path, url, field, "OnSuccess", "OnFail") + * 上传一个文件到远程服务器。 + * name:为上传后的文件名称; + * path:是文件绝对路径; + * url:为上传地址; + * field:为请求中name的值; + * 最后两个参数为回调函数名称; + */ + var l_uploadPath = GetDocParamsValue(l_doc, "uploadPath"); // 文件上载路径 + if (l_uploadPath == "") { + wps.alert("系统未传入文件上载路径,不能执行上传操作!"); + return; + } + + if (!wps.confirm("先保存文档,并开始上传到系统后台,请确认?")) { + return; + } + + var l_FieldName = GetDocParamsValue(l_doc, "uploadFieldName"); //上载到后台的字段名称 + if (l_FieldName == "") { + l_FieldName = wps.PluginStorage.getItem("DefaultUploadFieldName"); // 默认为‘file’ + } + + var l_UploadName = GetDocParamsValue(l_doc, "uploadFileName"); //设置OA传入的文件名称参数 + if (l_UploadName == "") { + l_UploadName = l_doc.Name; //默认文件名称就是当前文件编辑名称 + } + + var l_DocPath = l_doc.FullName; // 文件所在路径 + + if (pIsOnlineOADoc(l_doc) == false) { + //对于本地磁盘文件上传OA,先用Save方法保存后,再上传 + //设置用户保存按钮标志,避免出现禁止OA文件保存的干扰信息 + wps.PluginStorage.setItem("OADocUserSave", EnumDocSaveFlag.OADocSave); + l_doc.Save(); //执行一次保存方法 + //设置用户保存按钮标志 + wps.PluginStorage.setItem("OADocUserSave", EnumDocSaveFlag.NoneOADocSave); + //落地文档,调用UploadFile方法上传到OA后台 + try { + //调用OA助手的上传方法 + UploadFile(l_UploadName, l_DocPath, l_uploadPath, l_FieldName, OnUploadToServerSuccess, OnUploadToServerFail); + } catch (err) { + alert("上传文件失败!请检查系统上传参数及网络环境!"); + } + } else { + // 不落地的文档,调用 Document 对象的不落地上传方法 + wps.PluginStorage.setItem("OADocUserSave", EnumDocSaveFlag.OADocSave); + try { + //调用不落地上传方法 + l_doc.SaveAsUrl(l_UploadName, l_uploadPath, l_FieldName, "OnUploadToServerSuccess", "OnUploadToServerFail"); + } catch (err) { + alert("上传文件失败!请检查系统上传参数及网络环境,重新上传。"); + } + wps.PluginStorage.setItem("OADocUserSave", EnumDocSaveFlag.NoneOADocSave); + } + + //获取OA传入的 转其他格式上传属性 + var l_suffix = GetDocParamsValue(l_doc, "suffix"); + if (l_suffix == "") { + console.log("上传需转换的文件后缀名错误,无妨进行转换上传!"); + return; + } + + //判断是否同时上传PDF等格式到OA后台 + var l_uploadWithAppendPath = GetDocParamsValue(l_doc, "uploadWithAppendPath"); //标识是否同时上传OFD、PDF等格式的文件 + if (l_uploadWithAppendPath == "1") { + //调用转 pdf格式函数,强制关闭转换修订痕迹 + pDoChangeToOtherDocFormat(l_doc, l_suffix, false, false); // + } + return; +} + +/** + * 执行另存为本地文件操作 + */ +function OnBtnSaveAsLocalFile() { + + //初始化临时状态值 + wps.PluginStorage.setItem("OADocUserSave", false); + wps.PluginStorage.setItem("IsInCurrOADocSaveAs", false); + + //检测是否有文档正在处理 + var l_doc = wps.EtApplication().ActiveWorkbook; + if (!l_doc) { + alert("WPS当前没有可操作文档!"); + return; + } + + // 设置WPS文档对话框 2 FileDialogType:=msoFileDialogSaveAs + var l_ksoFileDialog = wps.EtApplication().FileDialog(2); + l_ksoFileDialog.InitialFileName = l_doc.Name; //文档名称 + + if (l_ksoFileDialog.Show() == -1) { // -1 代表确认按钮 + wps.PluginStorage.setItem("OADocUserSave", true); //设置保存为临时状态,在Save事件中避免OA禁止另存为对话框 + l_ksoFileDialog.Execute(); //会触发保存文档的监听函数 + + pSetNoneOADocFlag(l_doc); + wps.ribbonUI.Invalidate(); //刷新Ribbon的状态 + }; +} + +/** + * 获取对象中属性的值 + * @param {*} params + * @param {*} Key + */ +function GetParamsValue(Params, Key) { + if (typeof (Params) == "undefined") { + return ""; + } + + var l_rtnValue = Params[Key]; + return l_rtnValue; +} + + +function OnAction(control) { + var eleId; + if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 + eleId = control.Id; + } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 + eleId = arguments[1].Id; + } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 + eleId = arguments[1].Id; + } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 + eleId = arguments[2].Id; + } + switch (strId) { + case "btnSaveToServer": + OnBtnSaveToServer(); + break; + case "btnSaveAsFile": + OnBtnSaveAsLocalFile(); + break; + default: + ; + } + return true; +} + +function OnGetEnabled(control) { + var eleId; + if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 + eleId = control.Id; + } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 + eleId = arguments[1].Id; + } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 + eleId = arguments[1].Id; + } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 + eleId = arguments[2].Id; + } + switch (eleId) { + case "btnSaveToServer": //保存到OA服务器的相关按钮。判断,如果非OA文件,禁止点击 + return OnSetSaveToOAEnable(); + case "btnSaveAsFile": + let doc=wps.EtApplication().ActiveWorkbook; + let l_Params=wps.PluginStorage.getItem(doc.FullName); + let OADocLandMode=JSON.parse(l_Params).OADocLandMode + return !OADocLandMode + default: + ; + } + return true; +} + +function OnGetVisible(control) { + var eleId; + if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 + eleId = control.Id; + } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 + eleId = arguments[1].Id; + } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 + eleId = arguments[1].Id; + } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 + eleId = arguments[2].Id; + } + var l_value = false; + //按照 OA文档传递过来的属性进行判断 + l_value = pShowRibbonGroupByOADocParam(eleId); + return l_value; +} + +function GetImage(control) { + var eleId; + if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 + eleId = control.Id; + } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 + eleId = arguments[1].Id; + } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 + eleId = arguments[1].Id; + } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 + eleId = arguments[2].Id; + } + switch (eleId) { + case "btnSaveToServer": //保存到OA后台服务端 + return "./icon/w_Save.png"; + case "btnSaveAsFile": //另存为本地文件 + return "./icon/w_SaveAs.png"; + default: + ; + } + return "./icon/c_default.png"; +} + +function OnGetLabel(control) { + var eleId; + if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 + eleId = control.Id; + } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 + eleId = arguments[1].Id; + } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 + eleId = arguments[1].Id; + } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 + eleId = arguments[2].Id; + } + switch (eleId) { + case "btnSaveAsFile": + return "另存为本地"; + default: + ; + } + return ""; +} \ No newline at end of file diff --git a/test/oaassist/EtOAAssist/js/main.js b/test/oaassist/EtOAAssist/js/main.js new file mode 100644 index 0000000..81578c3 --- /dev/null +++ b/test/oaassist/EtOAAssist/js/main.js @@ -0,0 +1,9 @@ +if (typeof (window.wps) == "undefined") { + window.wps = window; +} +var time=new Date().getTime() //添加时间戳,防止js文件使用浏览器缓存 +document.write(""); +document.write(""); +document.write(""); +document.write(""); +document.write(""); \ No newline at end of file diff --git a/test/oaassist/EtOAAssist/package.json b/test/oaassist/EtOAAssist/package.json new file mode 100644 index 0000000..b945069 --- /dev/null +++ b/test/oaassist/EtOAAssist/package.json @@ -0,0 +1,12 @@ +{ + "name": "EtOAAssist", + "addonType": "et", + "version": "1.0.0", + "description": "这个工程为WPS表格项目一个简单的OA场景集成的WPS加载项——OA助手,旨在帮助大家能够快速理解并熟悉WPS加载项机制以及和浏览器调用交互的流程。", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} \ No newline at end of file diff --git a/test/oaassist/EtOAAssist/ribbon.xml b/test/oaassist/EtOAAssist/ribbon.xml new file mode 100644 index 0000000..2d8a051 --- /dev/null +++ b/test/oaassist/EtOAAssist/ribbon.xml @@ -0,0 +1,14 @@ + + + + + + + +
+ +
+ + + + + + + \ No newline at end of file diff --git a/test/oaassist/WpsOAAssist/index.html b/test/oaassist/WpsOAAssist/index.html new file mode 100644 index 0000000..887c288 --- /dev/null +++ b/test/oaassist/WpsOAAssist/index.html @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/test/oaassist/WpsOAAssist/js/common/common.js b/test/oaassist/WpsOAAssist/js/common/common.js new file mode 100644 index 0000000..3c02027 --- /dev/null +++ b/test/oaassist/WpsOAAssist/js/common/common.js @@ -0,0 +1,535 @@ +// -------------------------- 通用常量 --------------------------- + +//OA门户网站用接口,配置默认服务器接口 +var OA_DOOR = { + templateDataUrl: undefined, //正文模板列表接口 + templateBaseURL: undefined, //指定正文模板基础接口 + redHeadsPath: undefined, //默认红头模板列表获取路径 + getRedHeadPath: undefined, //默认获取红头文件路径 + bookmarkPath: undefined, //书签列表接口 + redHeadsPath: undefined, //默认红头模板列表获取路径 +} + +// -------------------------- 通用方法 --------------------------- +//去除字符串左边空格 +String.prototype.ltrim = function () { + return this.replace(/(^\s*)/g, ""); +} + +//去除字符串右边空格 +String.prototype.rtrim = function () { + return this.replace(/(\s*$)/g, ""); +} + +//扩展js string endwith,startwith方法 +String.prototype.endWith = function (str) { + if (str == null || str == "" || this.length == 0 || str.length > this.length) + return false; + if (this.substring(this.length - str.length) == str) + return true; + else + return false; +} + +String.prototype.startWith = function (str) { + if (str == null || str == "" || this.length == 0 || str.length > this.length) + return false; + if (this.substr(0, str.length) == str) + return true; + else + return false; +} + +//UTF-16转UTF-8 +function utf16ToUtf8(s) { + if (!s) { + return; + } + var i, code, ret = [], + len = s.length; + for (i = 0; i < len; i++) { + code = s.charCodeAt(i); + if (code > 0x0 && code <= 0x7f) { + //单字节 + //UTF-16 0000 - 007F + //UTF-8 0xxxxxxx + ret.push(s.charAt(i)); + } else if (code >= 0x80 && code <= 0x7ff) { + //双字节 + //UTF-16 0080 - 07FF + //UTF-8 110xxxxx 10xxxxxx + ret.push( + //110xxxxx + String.fromCharCode(0xc0 | ((code >> 6) & 0x1f)), + //10xxxxxx + String.fromCharCode(0x80 | (code & 0x3f)) + ); + } else if (code >= 0x800 && code <= 0xffff) { + //三字节 + //UTF-16 0800 - FFFF + //UTF-8 1110xxxx 10xxxxxx 10xxxxxx + ret.push( + //1110xxxx + String.fromCharCode(0xe0 | ((code >> 12) & 0xf)), + //10xxxxxx + String.fromCharCode(0x80 | ((code >> 6) & 0x3f)), + //10xxxxxx + String.fromCharCode(0x80 | (code & 0x3f)) + ); + } + } + + return ret.join(''); + +} +var Base64 = { + _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", + encode: function(e) { + var t = ""; + var n, r, i, s, o, u, a; + var f = 0; + e = Base64._utf8_encode(e); + while (f < e.length) { + n = e.charCodeAt(f++); + r = e.charCodeAt(f++); + i = e.charCodeAt(f++); + s = n >> 2; + o = (n & 3) << 4 | r >> 4; + u = (r & 15) << 2 | i >> 6; + a = i & 63; + if (isNaN(r)) { + u = a = 64 + } else if (isNaN(i)) { + a = 64 + } + t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a) + } + return t + }, + decode: function(e) { + var t = ""; + var n, r, i; + var s, o, u, a; + var f = 0; + e = e.replace(/[^A-Za-z0-9+/=]/g, ""); + while (f < e.length) { + s = this._keyStr.indexOf(e.charAt(f++)); + o = this._keyStr.indexOf(e.charAt(f++)); + u = this._keyStr.indexOf(e.charAt(f++)); + a = this._keyStr.indexOf(e.charAt(f++)); + n = s << 2 | o >> 4; + r = (o & 15) << 4 | u >> 2; + i = (u & 3) << 6 | a; + t = t + String.fromCharCode(n); + if (u != 64) { + t = t + String.fromCharCode(r) + } + if (a != 64) { + t = t + String.fromCharCode(i) + } + } + t = Base64._utf8_decode(t); + return t + }, + _utf8_encode: function(e) { + e = e.replace(/rn/g, "n"); + var t = ""; + for (var n = 0; n < e.length; n++) { + var r = e.charCodeAt(n); + if (r < 128) { + t += String.fromCharCode(r) + } else if (r > 127 && r < 2048) { + t += String.fromCharCode(r >> 6 | 192); + t += String.fromCharCode(r & 63 | 128) + } else { + t += String.fromCharCode(r >> 12 | 224); + t += String.fromCharCode(r >> 6 & 63 | 128); + t += String.fromCharCode(r & 63 | 128) + } + } + return t + }, + _utf8_decode: function(e) { + var t = ""; + var n = 0; + var r = c1 = c2 = 0; + while (n < e.length) { + r = e.charCodeAt(n); + if (r < 128) { + t += String.fromCharCode(r); + n++ + } else if (r > 191 && r < 224) { + c2 = e.charCodeAt(n + 1); + t += String.fromCharCode((r & 31) << 6 | c2 & 63); + n += 2 + } else { + c2 = e.charCodeAt(n + 1); + c3 = e.charCodeAt(n + 2); + t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63); + n += 3 + } + } + return t + } +} +//UTF-8转UTF-16 +function utf8ToUtf16(s) { + if (!s) { + return; + } + + var i, codes, bytes, ret = [], + len = s.length; + for (i = 0; i < len; i++) { + codes = []; + codes.push(s.charCodeAt(i)); + if (((codes[0] >> 7) & 0xff) == 0x0) { + //单字节 0xxxxxxx + ret.push(s.charAt(i)); + } else if (((codes[0] >> 5) & 0xff) == 0x6) { + //双字节 110xxxxx 10xxxxxx + codes.push(s.charCodeAt(++i)); + bytes = []; + bytes.push(codes[0] & 0x1f); + bytes.push(codes[1] & 0x3f); + ret.push(String.fromCharCode((bytes[0] << 6) | bytes[1])); + } else if (((codes[0] >> 4) & 0xff) == 0xe) { + //三字节 1110xxxx 10xxxxxx 10xxxxxx + codes.push(s.charCodeAt(++i)); + codes.push(s.charCodeAt(++i)); + bytes = []; + bytes.push((codes[0] << 4) | ((codes[1] >> 2) & 0xf)); + bytes.push(((codes[1] & 0x3) << 6) | (codes[2] & 0x3f)); + ret.push(String.fromCharCode((bytes[0] << 8) | bytes[1])); + } + } + return ret.join(''); + +} + +function currentTime() { + var now = new Date(); + + var year = now.getFullYear(); //年 + var month = now.getMonth() + 1; //月 + var day = now.getDate(); //日 + + var hh = now.getHours(); //时 + var mm = now.getMinutes(); //分 + var ss = now.getSeconds(); + var clock = year + ""; + + if (month < 10) + clock += "0"; + + clock += month + ""; + + if (day < 10) + clock += "0"; + + clock += day + ""; + + if (hh < 10) + clock += "0"; + + clock += hh + ""; + if (mm < 10) clock += '0'; + clock += mm; + if (ss < 10) clock += '0'; + clock += ss; + return (clock); +} + +/** + * 获取文件路径 + * @param {*} html 文件全称 + */ +function getHtmlURL(html) { + //弹出辅助窗格框 + var GetUrlPath = ()=> { + var e = document.location.toString(); + return -1 != (e = decodeURI(e)).indexOf("/") && (e = e.substring(0, e.lastIndexOf("/"))), e + } + + var url = GetUrlPath(); + + if (url.length != 0) { + url = url.concat("/" + html); + } else { + url = url.concat("./" + html); + } + return url; +} + +/** + * wps内弹出web页面 + * @param {*} html 文件名 + * @param {*} title 窗口标题 + * @param {*} hight 窗口高 + * @param {*} width 窗口宽 + */ +function OnShowDialog(html, title, height, width, bModal) { + var l_ActiveDoc = wps.WpsApplication().ActiveDocument; + if (!l_ActiveDoc) { + alert("WPS当前没有可操作文档!") + return; + } + if (typeof bModal == "undefined" || bModal == null) { + bModal = true; + } + width *= window.devicePixelRatio; + height *= window.devicePixelRatio; + var url = getHtmlURL(html); + wps.ShowDialog(url, title, height, width, bModal); +} + +/** + * 解析返回response的参数 + * @param {*} resp + * @return {*} body + */ +function handleResultBody(resp) { + var result = ""; + if (resp.Body) { + // 解析返回response的参数 + } + return result; +} + + +/** + * 判断WPS中的文件个数是否为0,若为0则关闭WPS函数 + * @param {*} name + */ +function closeWpsIfNoDocument() { + var wpsApp = wps.WpsApplication(); + var docs = wpsApp.Documents; + if (!docs || docs.Count == 0) { + wps.ApiEvent.Cancel = true; + //根据业务可以选择是否退出进程 wpsApp.Quit(); + } +} + +function activeTab() { + //启动WPS程序后,默认显示的工具栏选项卡为ribbon.xml中某一tab + if (wps.ribbonUI) + wps.ribbonUI.ActivateTab('WPSWorkExtTab'); +} + +function showOATab() { + wps.PluginStorage.setItem("ShowOATabDocActive", pCheckIfOADoc()); //根据文件是否为OA文件来显示OA菜单 + wps.ribbonUI.Invalidate(); // 刷新Ribbon自定义按钮的状态 +} + +function getDemoTemplatePath() { + var url = document.location.toString(); + url = decodeURI(url); + if (url.indexOf("/") != -1) { + url = url.substring(0, url.lastIndexOf("/")); + } + if (url.length !== 0) + url = url.concat("/template/红头文件.docx"); + + if (url.startsWith("file:///")) + url = url.substr("file:///".length); + return url; +} + +function getDemoSealPath() { + var url = document.location.toString(); + url = decodeURI(url); + if (url.indexOf("/") != -1) { + url = url.substring(0, url.lastIndexOf("/")); + } + if (url.length !== 0) + url = url.concat("/template/OA模板:公章.png"); + + if (url.startsWith("file:///")) + url = url.substr("file:///".length); + return url; +} + +function pGetParamName(data, attr) { + var start = data.indexOf(attr); + data = data.substring(start + attr.length); + return data; +} +/** + * 从requst中获取文件名(确保请求中有filename这个参数) + * @param {*} request + * @param {*} url + */ + function pGetFileName(request, url) { + var disposition = request.getResponseHeader("Content-Disposition"); + var filename = ""; + if (disposition) { + var matchs = pGetParamName(disposition, "filename="); + if (matchs) { + filename = decodeURIComponent(matchs); + } else { + filename = "petro" + Date.getTime(); + } + } else { + filename = url.substring(url.lastIndexOf("/") + 1); + filename=filename.split("?")[0] + } + return filename; +} + +function StringToUint8Array(string) { + var binLen, buffer, chars, i, _i; + binLen = string.length; + buffer = new ArrayBuffer(binLen); + chars = new Uint8Array(buffer); + for (var i = 0; i < binLen; ++i) { + chars[i] = String.prototype.charCodeAt.call(string, i); + } + return buffer; +} +/** + * WPS下载文件到本地打开(业务系统可根据实际情况进行修改) + * @param {*} url 文件流的下载路径 + * @param {*} callback 下载后的回调 + */ +function DownloadFile(url, callback) { + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (this.readyState == 4 && this.status == 200) { + //需要业务系统的服务端在传递文件流时,确保请求中的参数有filename + var fileName = pGetFileName(xhr, url) + //落地打开模式下,WPS会将文件下载到本地的临时目录,在关闭后会进行清理 + var path = wps.Env.GetTempPath() + "/" + fileName + var reader = new FileReader(); + reader.onload = function () { + wps.FileSystem.writeAsBinaryString(path, reader.result); + callback(path); + }; + reader.readAsBinaryString(xhr.response); + } + } + xhr.open('GET', url); + xhr.responseType = 'blob'; + xhr.send(); +} +/** + * WPS上传文件到服务端(业务系统可根据实际情况进行修改,为了兼容中文,服务端约定用UTF-8编码格式) + * @param {*} strFileName 上传到服务端的文件名称(包含文件后缀) + * @param {*} strPath 上传文件的文件路径(文件在操作系统的绝对路径) + * @param {*} uploadPath 上传文件的服务端地址 + * @param {*} strFieldName 业务调用方自定义的一些内容可通过此字段传递,默认赋值'file' + * @param {*} OnSuccess 上传成功后的回调 + * @param {*} OnFail 上传失败后的回调 + */ +function UploadFile(strFileName, strPath, uploadPath, strFieldName, OnSuccess, OnFail) { + var xhr = new XMLHttpRequest(); + xhr.open('POST', uploadPath); + + var fileData = wps.FileSystem.readAsBinaryString(strPath); + var data = new FakeFormData(); + if (strFieldName == "" || typeof strFieldName == "undefined"){//如果业务方没定义,默认设置为'file' + strFieldName = 'file'; + } + data.append(strFieldName, { + name: utf16ToUtf8(strFileName), //主要是考虑中文名的情况,服务端约定用utf-8来解码。 + type: "application/octet-stream", + getAsBinary: function () { + return fileData; + } + }); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + if (xhr.status == 200) + OnSuccess(xhr.response) + else + OnFail(xhr.response); + } + }; + xhr.setRequestHeader("Cache-Control", "no-cache"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + if (data.fake) { + xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + data.boundary); + var arr = StringToUint8Array(data.toString()); + xhr.send(arr); + } else { + xhr.send(data); + } +} + +/** + * 打开WPS后通知到业务系统,可根据需求扩展 + * @param {*} p_Url 业务方接受请求的地址 + */ +function NotifyToServer(p_Url) { + $.ajax({ + url: p_Url, // URL + '/wps/wpsCanOpen', + async: true, + method: "post", + dataType: 'json' + }); +} + +/** + * 更新编辑状态 + * @param {*} p_Url 要传入OA端,通知业务系统,当前文档所处的编辑状态的URL地址路径 + * @param {*} p_OpenUrl 当前文档从业务系统打开时的入口URL,这个URL包含业务系统开发者需要传入的ID等参数 + * @param {*} docId 文档id + * @param {*} state 0-正在编辑中 1-文件保存 2-文件关闭 状态可根据需要进行自定义扩展 + */ +function UpdateEditState(p_Url, p_OpenUrl, docId, state) { + var formData = { + "openUrl": p_OpenUrl, + "docId": docId, + "state": state + }; + $.ajax({ + url: p_Url, //URL + '/document/stateMonitor', + async: false, + data: formData, + method: "post", + dataType: 'json', + success: function (response) { + if (response == "success") { + console.log(response); + } + }, + error: function (response) { + console.log(response); + } + }); +} + +/** + * 作用:判断文档关闭后,如果系统已经没有打开的文档了,则设置回初始用户名 + */ +function pSetWPSAppUserName() { + //文档全部关闭的情况下,把WPS初始启动的用户名设置回去 + if (wps.WpsApplication().Documents.Count == 1) { + var l_strUserName = wps.PluginStorage.getItem(constStrEnum.WPSInitUserName); + wps.WpsApplication().UserName = l_strUserName; + } +} + +/** + * 设置文档参数的属性值 + * @param {*} Doc + * @param {*} Key + * @param {*} Value + */ +function SetDocParamsValue(Doc, Key, Value) { + if (!Doc || !Key) { + return; + } + + var l_Params = wps.PluginStorage.getItem(Doc.DocID); + if (!l_Params) { + return; + } + + var l_objParams = JSON.parse(l_Params); + if (!(typeof(l_objParams) == "undefined")) { + l_objParams[Key] = Value; + } + + //把属性值整体再写回原来的文档ID中 + wps.PluginStorage.setItem(Doc.DocID, JSON.stringify(l_objParams)); +} diff --git a/test/oaassist/WpsOAAssist/js/common/enum.js b/test/oaassist/WpsOAAssist/js/common/enum.js new file mode 100644 index 0000000..77b5849 --- /dev/null +++ b/test/oaassist/WpsOAAssist/js/common/enum.js @@ -0,0 +1,115 @@ +/** + * WPS常用的API枚举值,具体参与API文档 + */ +var WPS_Enum = { + wdDoNotSaveChanges: 0, + wdFormatPDF: 17, + wdFormatOpenDocumentText: 23, + wdFieldFormTextInput: 70, + wdAlertsNone: 0, + wdDialogFilePageSetup: 178, + wdDialogFilePrint: 88, + wdRelativeHorizontalPositionPage: 1, + wdGoToPage: 1, + wdPropertyPages: 14, + wdRDIComments: 1, + wdDialogInsertDateTime: 165, + msoCTPDockPositionLeft: 0, + msoCTPDockPositionRight: 2, + /** + * 将形状嵌入到文字中。 + */ + wdWrapInline: 7, + /** + * 将形状放在文字前面。 请参阅 wdWrapFront。 + */ + wdWrapNone: 3, + /** + * 使文字环绕形状。 行在形状的另一侧延续。 + */ + wdWrapSquare: 0, + /** + * 使文字环绕形状。 + */ + wdWrapThrough: 2, + /** + * 使文字紧密地环绕形状。 + */ + wdWrapTight: 1, + /** + * 将文字放在形状的上方和下方。 + */ + wdWrapTopBottom: 4, + /** + * 将形状放在文字后面。 + */ + wdWrapBehind: 5, + /** + * 将形状放在文字前面。 + */ + wdWrapFront: 6 +} + +/** + * WPS加载项自定义的枚举值 + */ +var constStrEnum = { + AllowOADocReOpen: "AllowOADocReOpen", + AutoSaveToServerTime: "AutoSaveToServerTime", + bkInsertFile: "bkInsertFile", + buttonGroups: "buttonGroups", + CanSaveAs: "CanSaveAs", + copyUrl: "copyUrl", + DefaultUploadFieldName: "DefaultUploadFieldName", + disableBtns: "disableBtns", + insertFileUrl: "insertFileUrl", + IsInCurrOADocOpen: "IsInCurrOADocOpen", + IsInCurrOADocSaveAs: "IsInCurrOADocSaveAs", + isOA: "isOA", + notifyUrl: "notifyUrl", + OADocCanSaveAs: "OADocCanSaveAs", + OADocLandMode: "OADocLandMode", + OADocUserSave: "OADocUserSave", + openType: "openType", + picPath: "picPath", + picHeight: "picHeight", + picWidth: "picWidth", + redFileElement: "redFileElement", + revisionCtrl: "revisionCtrl", + ShowOATabDocActive: "ShowOATabDocActive", + SourcePath: "SourcePath", + /** + * 保存文档到业务系统服务端时,另存一份其他格式到服务端,其他格式支持:.pdf .ofd .uot .uof + */ + suffix: "suffix", + templateDataUrl: "templateDataUrl", + TempTimerID: "TempTimerID", + /** + * 文档上传到业务系统的保存地址:服务端接收文件流的地址 + */ + uploadPath: "uploadPath", + /** + * 文档上传到服务端后的名称 + */ + uploadFieldName: "uploadFieldName", + /** + * 文档上传时的名称,默认取当前活动文档的名称 + */ + uploadFileName: "uploadFileName", + uploadAppendPath: "uploadAppendPath", + /** + * 标志位: 1 在保存到业务系统时再保存一份suffix格式的文档, 需要和suffix参数配合使用 + */ + uploadWithAppendPath: "uploadWithAppendPath", + userName: "userName", + WPSInitUserName: "WPSInitUserName", + taskpaneid: "taskpaneid", + /** + * 是否弹出上传前确认和成功后的确认信息:true|弹出,false|不弹出 + */ + Save2OAShowConfirm: "Save2OAShowConfirm", + /** + * 修订状态标志位 + */ + RevisionEnableFlag: "RevisionEnableFlag" +} \ No newline at end of file diff --git a/test/oaassist/WpsOAAssist/js/common/func_docEvents.js b/test/oaassist/WpsOAAssist/js/common/func_docEvents.js new file mode 100644 index 0000000..f63b9cb --- /dev/null +++ b/test/oaassist/WpsOAAssist/js/common/func_docEvents.js @@ -0,0 +1,232 @@ +// 打印前监听事件 +function OnDocumentBeforePrint(doc) { + return; +} + +//切换窗口时触发的事件 +function OnWindowActivate() { + var l_doc = wps.WpsApplication().ActiveDocument; + SetCurrDocEnvProp(l_doc); // 设置当前文档对应的用户名 + showOATab(); // 根据文件是否为OA文件来显示OA菜单再进行刷新按钮 + setTimeout(activeTab, 2000); // 激活页面必须要页签显示出来,所以做1秒延迟 + return; +} + +/** + * 作用:判断OA文档是否被另存为了 + */ +function CheckIfOADocSaveAs(doc) { + if (!doc) { + return; + } + // 获取OA文档的原始保存路径 + var l_Path = GetDocParamsValue(doc, constStrEnum.SourcePath); + // 原路径和当前文件的路径对比 + return l_Path == doc.FullName; +} + + +// 当文件保存前触发的事件 +function OnDocumentBeforeSave(doc) { + //设置变量,判断是否当前用户按了自定义的OA文件保存按钮 + if(wps.WpsApplication().ActiveDocument&&doc.DocID==wps.WpsApplication().ActiveDocument.DocID){ + var l_IsOADocButtonSave = false; + l_IsOADocButtonSave = wps.PluginStorage.getItem(constStrEnum.OADocUserSave); + + //根据传入参数判断当前文档是否能另存为,默认不能另存为 + if (pCheckCurrOADocCanSaveAs(doc) == false) { //先根据OA助手的默认设置判断是否允许OA文档另存为操作 + //0.如果配置文件:OA文档不允许另存为,则再判断 + //1.先判断是否是在线文档且是通过WPS自身按钮或快捷键保存,则取消弹出另存到本地的弹出框 + if (pIsOnlineOADoc(doc) == true && l_IsOADocButtonSave == false) { + alert("来自OA的不落地文档,禁止另存为本地文档!"); + //如果是OA文档,则禁止另存为 + wps.ApiEvent.Cancel = true; + } + //2.如果是落地打开的OA文档并且通过WPS自身按钮或者快捷键保存,则执行保存到本地临时目录,取消弹出对话框 + if (pIsOnlineOADoc(doc) == false && l_IsOADocButtonSave == false){ + //用户手动另存为操作时,在这里被屏蔽掉 + doc.Save(); + //如果是OA文档,则禁止另存为 + wps.ApiEvent.Cancel = true; + } + } + //保存文档后,也要刷新一下Ribbon按钮的状态 + showOATab(); + }else{ + wps.ApiEvent.Cancel=true; + } + return; +} + + +//文档保存前关闭事件 +/** + * 作用: + * @param {*} doc + */ +function OnDocumentBeforeClose(doc) { + console.log('OnDocumentBeforeClose'); + var l_fullName = doc.FullName; + var l_bIsOADoc = false; + l_bIsOADoc = CheckIfDocIsOADoc(doc); //判断是否OA文档要关闭 + if (l_bIsOADoc == false) { // 非OA文档不做处理 + return; + } + //判断是否只读的文档,或受保护的文档,对于只读的文档,不给予保存提示 + if (pISOADocReadOnly(doc) == false) { + if (doc.Saved == false) { //如果OA文档关闭前,有未保存的数据 + if (wps.confirm("系统文件有改动,是否提交后关闭?" + "\n" + "确认后请按上传按钮执行上传操作。取消则继续关闭文档。")) { + wps.ApiEvent.Cancel = true; + return; + } + } + } + // 有未保存的数据,确认无需保存直接关闭 + doc.Close(wps.Enum&&wps.Enum.wdDoNotSaveChanges||0); // 不保存待定的更改。枚举值兼容性写法 + closeWpsIfNoDocument(); // 判断WPS中的文件个数是否为0,若为0则关闭WPS函数 + wps.FileSystem.Remove(l_fullName); +} + + +//文档保存后关闭事件 +function OnDocumentAfterClose(doc) { + console.log("OnDocumentAfterClose"); + var l_NofityURL = GetDocParamsValue(doc, constStrEnum.notifyUrl); + if (l_NofityURL) { + l_NofityURL = l_NofityURL.replace("{?}", "3"); //约定:参数为3则文档关闭 + console.log("" + l_NofityURL); + NotifyToServer(l_NofityURL); + } + + pRemoveDocParam(doc); // 关闭文档时,移除PluginStorage对象的参数 + pSetWPSAppUserName(); // 判断文档关闭后,如果系统已经没有打开的文档了,则设置回初始用户名 +} + +//文档打开事件 +function OnDocumentOpen(doc) { + //设置当前新增文档是否来自OA的文档 + // if (wps.PluginStorage.getItem(constStrEnum.IsInCurrOADocOpen) == false) { + // //如果是用户自己在WPS环境打开文档,则设置非OA文档标识 + // console.log(wps.PluginStorage.getItem(wps.WpsApplication().ActiveDocument.DocID)) + // pSetNoneOADocFlag(doc); + // console.log(wps.PluginStorage.getItem(wps.WpsApplication().ActiveDocument.DocID)) + // } + OnWindowActivate(); + ChangeOATabOnDocOpen(); //打开文档后,默认打开Tab页 + setTimeout(activeTab,2000); // 激活OA助手菜单 +} + +//新建文档事件 +function OnDocumentNew(doc) { + //设置当前新增文档是否来自OA的文档 + // if (wps.PluginStorage.getItem(constStrEnum.IsInCurrOADocOpen) == false) { + // //如果是用户自己在WPS环境打开文档,则设置非OA文档标识 + // pSetNoneOADocFlag(doc); + // } + ChangeOATabOnDocOpen(); // 打开OA助手Tab菜单页 + wps.ribbonUI.Invalidate(); // 刷新Ribbon按钮的状态 +} + +/** + * 作用:判断当前文档是否是只读文档 + * 返回值:布尔 + */ +function pISOADocReadOnly(doc) { + if (!doc) { + return false; + } + var l_openType = GetDocParamsValue(doc, constStrEnum.openType); // 获取OA传入的参数 openType + if (l_openType == "") { + return false; + } + try { + if (l_openType.protectType != -1) { // -1 为未保护 + return true; + } + } catch (err) { + return false; + } +} + + +/** + * 作用:根据当前活动文档的情况判断,当前文档适用的系统参数,例如:当前文档对应的用户名称等 + */ +function SetCurrDocEnvProp(doc) { + if (!doc) return; + var l_bIsOADoc = false; + l_bIsOADoc = pCheckIfOADoc(doc); + + //如果是OA文件,则按OA传来的用户名设置WPS OA助手WPS用户名设置按钮冲突 + if (l_bIsOADoc == true) { + var l_userName = GetDocParamsValue(doc, constStrEnum.userName); + if (l_userName != "") { + wps.WpsApplication().UserName = l_userName; + return; + } + } + //如果是非OA文件或者参数的值是空值,则按WPS安装默认用户名设置 + wps.WpsApplication().UserName = wps.PluginStorage.getItem(constStrEnum.WPSInitUserName); +} + + + +/* + 入口参数:doc + 功能说明:判断当前文档是否能另存为本地文件 + 返回值:布尔值true or false +*/ +function pCheckCurrOADocCanSaveAs(doc) { + //如果是非OA文档,则允许另存为 + if (CheckIfDocIsOADoc(doc) == false) return true; + + //对于来自OA系统的文档,则获取该文档对应的属性参数 + var l_CanSaveAs = GetDocParamsValue(doc, constStrEnum.CanSaveAs); + + //判断OA传入的参数 + if (typeof (l_CanSaveAs) == "boolean") { + return l_CanSaveAs; + } + return false; +} + +/** + * 作用:文档关闭后,删除对应的PluginStorage内的参数信息 + * 返回值:没有返回值 + * @param {*} doc + */ +function pRemoveDocParam(doc) { + if (!doc) return; + wps.PluginStorage.removeItem(doc.DocID); + return; +} + +/** + * 作用:判断当前文档是否从OA来的文档,如果非OA文档(就是本地新建或打开的文档,则设置EnumOAFlag 标识) + * 作用:设置非OA文档的标识状态 + * @param {*} doc + * 返回值:无 + */ +function pSetNoneOADocFlag(doc) { + if (!doc) return; + var l_param = wps.PluginStorage.getItem(doc.DocID); //定义JSON文档参数 + var l_objParams = new Object(); + if (l_param) { + l_objParams = JSON.parse(l_param); + } + l_objParams.isOA = EnumOAFlag.DocFromNoOA; // 新增非OA打开文档属性 + wps.PluginStorage.setItem(doc.DocID, JSON.stringify(l_objParams)); // 存入内存中 +} + +/** + * 作用:根据设置判断打开文件是否默认激活OA助手工具Tab菜单 + * 返回值:无 + */ +function ChangeOATabOnDocOpen() { + var l_ShowOATab = true; //默认打开 + l_ShowOATab = wps.PluginStorage.getItem(constStrEnum.ShowOATabDocActive); + if (l_ShowOATab == true) { + setTimeout(activeTab,500); + // wps.ribbonUI.ActivateTab("WPSWorkExtTab"); //新建文档时,自动切换到OA助手状态 + } +} \ No newline at end of file diff --git a/test/oaassist/WpsOAAssist/js/common/func_docProcess.js b/test/oaassist/WpsOAAssist/js/common/func_docProcess.js new file mode 100644 index 0000000..0e48574 --- /dev/null +++ b/test/oaassist/WpsOAAssist/js/common/func_docProcess.js @@ -0,0 +1,904 @@ +/** + * 从OA调用传来的指令,打开本地新建文件 + * @param {*} fileUrl 文件url路径 + */ +function NewFile(params) { + //获取WPS Application 对象 + var wpsApp = wps.WpsApplication(); + wps.PluginStorage.setItem(constStrEnum.IsInCurrOADocOpen, true); //设置OA打开文档的临时状态 + //判断一下isOfficialDocument是否通过公文写作打开 + var doc; + if (params.isOfficialDocument) { + wps.Application.GetApplicationEx().NewOfficialDocument(); //新增使用公文写作打开的公文 + doc = wpsApp.ActiveDocument; + } else { + doc = wpsApp.Documents.Add(); //新增OA端文档 + } + wps.PluginStorage.setItem(constStrEnum.IsInCurrOADocOpen, false); + + //检查系统临时文件目录是否能访问 + if (wps.Env && wps.Env.GetTempPath) { + if (params.newFileName) { + //按OA传入的文件名称保存 + doc.SaveAs2($FileName = wps.Env.GetTempPath() + "/" + params.newFileName, undefined, undefined, undefined, false); + } else { + //OA传入空文件名称,则保存成系统时间文件 + if (params.isOfficialDocument) { + doc.SaveAs2($FileName = wps.Env.GetTempPath() + "/OA_" + currentTime(), 0, undefined, undefined, false); + } else { + doc.SaveAs2($FileName = wps.Env.GetTempPath() + "/OA_" + currentTime(), undefined, undefined, undefined, false); + } + } + } else { + alert("文档保存临时目录出错!不能保存新建文档!请联系系统开发商。"); + } + + var l_NofityURL = GetParamsValue(params, constStrEnum.notifyUrl); + if (l_NofityURL) { + NotifyToServer(l_NofityURL.replace("{?}", "1")); + } + + //Office文件打开后,设置该文件属性:从服务端来的OA文件 + pSetOADocumentFlag(doc, params); + //设置当前文档为 本地磁盘落地模式 + DoSetOADocLandMode(doc, EnumDocLandMode.DLM_LocalDoc); + //强制执行一次Activate事件 + OnWindowActivate(); + wps.WpsApplication().WindowState=1; + wps.WpsApplication().Activate(); //把WPS对象置前 + + return doc; //返回新创建的Document对象 +} + +/** + * 打开服务器上的文件 + * @param {*} fileUrl 文件url路径 + */ +function OpenFile(params) { + var l_strFileUrl = params.fileName; //来自OA网页端的OA文件下载路径 + var doc; + var l_IsOnlineDoc = false; //默认打开的是不落地文档 + if (l_strFileUrl) { + //下载文档之前,判断是否已下载该文件 + if (pCheckIsExistOpenOADoc(l_strFileUrl) == true) { + //如果找到相同OA地址文档,则给予提示 + wps.WpsApplication().WindowState=1; + wps.WpsApplication().Activate(); //把WPS对象置前 + //根据OA助手对是否允许再次打开相同文件的判断处理 + var l_AllowOADocReOpen = false; + l_AllowOADocReOpen = wps.PluginStorage.getItem(constStrEnum.AllowOADocReOpen); + if (l_AllowOADocReOpen == false) { + alert("已打开相同的OA文件,请关闭之前的文件,再次打开。"); + wps.WpsApplication().Activate(); + return null; + } else { + //处理重复打开相同OA 文件的方法 + var nDocCount = wps.WpsApplication().Documents.Count; + pReOpenOADoc(l_strFileUrl); + //重复打开的文档采用不落地的方式打开 + // 不落地方式打开文档判断落地比较多,V1版本先暂时关闭 + l_IsOnlineDoc = true; + var nDocCount_New = wps.WpsApplication().Documents.Count; + if (nDocCount_New > nDocCount) { + doc = wps.WpsApplication().ActiveDocument; + } + } + } else { + //如果当前没有打开文档,则另存为本地文件,再打开 + if (l_strFileUrl.startWith("http")) { // 网络文档 + DownloadFile(l_strFileUrl, function(path) { + if (path == "") { + alert("从服务端下载路径:" + l_strFileUrl + "\n" + "获取文件下载失败!"); + return null; + } + + doc = pDoOpenOADocProcess(params, path); + pOpenFile(doc, params, l_IsOnlineDoc); + }); + return; + } else { //本地文档 + doc = pDoOpenOADocProcess(params, l_strFileUrl); + if (doc) + doc.SaveAs2($FileName = wps.Env.GetTempPath() + "/" + doc.Name, undefined, undefined, undefined, false); + } + } + } else { + //fileURL 如果为空,则按新建OA本地文件处理 + NewFile(params); + } + //如果打开pdf等其他非Office文档,则doc对象为空 + if (!doc) { + return null; + } + + pOpenFile(doc, params, l_IsOnlineDoc); +} + +/** + * 作用:文档打开后执行的动作集合 + * @param {*} doc 文档对象 + * @param {*} params 前端传递的参数集合 + * @param {*} isOnlineDoc 在线打开/落地打开 + */ +function pOpenFile(doc, params, isOnlineDoc) { + var l_IsOnlineDoc = isOnlineDoc + //Office文件打开后,设置该文件属性:从服务端来的OA文件 + pSetOADocumentFlag(doc, params) + //设置当前文档为 本地磁盘落地模式 + if (l_IsOnlineDoc == true) { + DoSetOADocLandMode(doc, EnumDocLandMode.DLM_OnlineDoc); + } else { + DoSetOADocLandMode(doc, EnumDocLandMode.DLM_LocalDoc); + } + + if (GetParamsValue(params, constStrEnum.templateDataUrl)) { + GetServerTemplateData(doc, params[constStrEnum.templateDataUrl]); + } + + if (GetParamsValue(params, constStrEnum.insertFileUrl)) { + InsertRedHeadDoc(doc); + } + + var l_NofityURL = GetParamsValue(params, constStrEnum.notifyUrl); + if (l_NofityURL) { + l_NofityURL = l_NofityURL.replace("{?}", "1"); //约定:参数为1则代码打开状态 + NotifyToServer(l_NofityURL); + } + //重新设置工具条按钮的显示状态 + pDoResetRibbonGroups(); + // 触发切换窗口事件 + OnWindowActivate(); + // 把WPS对象置前 + wps.WpsApplication().WindowState=1; + wps.WpsApplication().Activate(); + return doc; +} + + + +/** + * 套用模板插入文字/图片/文档 + * * params参数结构 + * params:{ + * 'docId': docId, //文档ID + * 'templateURL':'',获取模板接口 + * 'fileName':'',获取文档接口 + * 'uploadPath':'',文档保存上传接口 + * } + * 这个功能要求服务端传来的模板JSON数据字符串,支持三种类型定义: + * text 类型:直接插入对应的书签位置 + * link 类型: 把对应的URL的文件插入到指定的书签位置 + * pic 类型: 把对应的URL的图片文件插入到指定的书签位置 + * @param {*} params + */ +function GetServerTemplateData(template, pTemplateDataUrl) { + //获取文档内容 + $.ajax({ + url: pTemplateDataUrl, + async: false, + method: "get", + dataType: 'json', + success: function(res) { + var data = res; + let Bookmarks = template.Bookmarks; + data.forEach(function(it) { + + var bookmark = Bookmarks.Item(it.name); + let bookStart = bookmark.Range.Start; + let bookEnd = bookmark.Range.End; + let start = template.Range().End + //方案1,直接替换,手动添加书签 + // if (bookmark) { + // if (!it.type || it.type === "text") { + // bookmark.Range.Text = it.text; + // } else if (it.type === "link") { + // bookmark.Range.InsertFile(it.text); + // } else if (it.type === "pic") { + // bookmark.Range.InlineShapes.AddPicture(it.text); + // } + // } + // let end = template.Range().End + // let range=bookmark.Range; + // if (!Bookmarks.Exists(bookmark.Name)) + // Bookmarks.Add(bookmark.Name, range.SetRange(bookStart, bookEnd + (end - start))) + + //方案2,不完全替换 + if(bookmark){ + if (!it.type || it.type === "text") { + bookmark.Range.InsertBefore(it.text); + } else if (it.type === "link") { + bookmark.Range.InsertFile(it.text); + } else if (it.type === "pic") { + bookmark.Range.InlineShapes.AddPicture(it.text); + } + } + var selection=wps.WpsApplication().ActiveWindow.Selection; + if (bookmark.Range.Text) { + selection.Start = bookmark.Range.End - (bookEnd - bookStart); + selection.End = bookmark.Range.End; + selection.Cut(); + } else { + selection.Start = bookmark.Range.End; + selection.End = bookmark.Range.End+it.text.length; + ActiveDocument.Bookmarks.Add(bookmark.Name, selection.Range); + } + }) + } + }); +} + +/** + * 打开服务端的文档(不落地) + * @param {*} fileUrl 文件url路径 + */ +function OpenOnLineFile(OAParams) { + //OA参数如果为空的话退出 + if (!OAParams) return; + + //获取在线文档URL + var l_OAFileUrl = OAParams.fileName; + var l_doc; + if (l_OAFileUrl) { + //下载文档不落地(16版WPS的925后支持) + wps.WpsApplication().Documents.OpenFromUrl(l_OAFileUrl, "OnOpenOnLineDocSuccess", "OnOpenOnLineDocDownFail"); + l_doc = wps.WpsApplication().ActiveDocument; + } + //执行文档打开后的方法 + pOpenFile(l_doc, OAParams, true); + return l_doc; +} + + +/** + * 打开在线文档成功后触发事件 + * @param {*} resp + */ +function OnOpenOnLineDocSuccess(resp) { + +} + + +/** + * 打开在线不落地文档出现失败时,给予错误提示 + */ +function OnOpenOnLineDocDownFail(res) { + var err={} + try{ + res=JSON.parse(res) + err.Body=Base64.decode(res.Body) + err.Headers=Base64.decode(JSON.stringify(res.Headers)) + console.log(err) + }catch(err){ + + } + alert("打开在线不落地文档失败!请尝试重新打开。"); + return; +} + +/** + * 参数: + * doc : 当前OA文档的Document对象 + * DocLandMode : 落地模式设置 + */ +function DoSetOADocLandMode(doc, DocLandMode) { + if (!doc) return; + var l_Param = wps.PluginStorage.getItem(doc.DocID); + var l_objParam = JSON.parse(l_Param); + //增加属性,或设置 + l_objParam.OADocLandMode = DocLandMode; //设置OA文档的落地标志 + + var l_p = JSON.stringify(l_objParam); + //将OA文档落地模式标志存入系统变量对象保存 + + wps.PluginStorage.setItem(doc.DocID, l_p); + +} + + +/** + * 作用:设置Ribbon工具条的按钮显示状态 + * @param {*} paramsGroups + */ +function pDoResetRibbonGroups(paramsGroups) { + +} + +/** + * 作用:打开文档处理的各种过程,包含:打开带密码的文档,保护方式打开文档,修订方式打开文档等种种情况 + * params Object OA Web端传来的请求JSON字符串,具体参数说明看下面数据 + * TempLocalFile : 字符串 先把文档从OA系统下载并保存在Temp临时目录,这个参数指已经下载下来的本地文档地址 + * ----------------------以下是OA参数的一些具体规范名称 + * docId String 文档ID + * uploadPath String 保存文档接口 + * fileName String 获取服务器文档接口(不传即为新建空文档) + * suffix String ".pdf|.uot",可传多个,用“|”分割,保存时会按照所传的值转成对应的格式文档并上传 + * userName String 用于更改显示修改人的用户名 + * strBookmarkDataPath string 书签列表 (可不传,可以在OA助手config.js中配置) + * templatePath string 模板列表 (可不传,可以在OA助手config.js中配置) + * buttonGroups string 自定义按钮组 (可不传,不传显示所有按钮) + * revisionCtrl String 痕迹控制 ,不传正常打开 + * bOpenRevision String true(打开)false(关闭)修订 + * bShowRevision String true(显示)/false(关闭)痕迹 + * openType String 文档打开方式 ,不传正常打开 + * protectType String 文档保护类型,-1:不启用保护模式,0:只允许对现有内容进行修订,1:只允许添加批注,2:只允许修改窗体域,3:只读 + * password String密码 + */ +function pDoOpenOADocProcess(params, TempLocalFile) { + var l_ProtectType = -1; //默认文档保护类型 -1 为不启用保护 + var l_ProtectPassword = ""; //默认文档密码为空 + + var l_strDocPassword = ""; //打开文档密码参数 + var l_bOpenRevision = false; //初始化关闭修订模式 + var l_bShowRevision = false; //初始化不显示修订气泡样式 + + for (var key = "" in params) { + switch (key.toUpperCase()) // + { + case "userName".toUpperCase(): //修改当前文档用户名 + wps.WpsApplication().UserName = params[key]; + break; + case "openType".toUpperCase(): + l_ProtectType = params[key].protectType; //获取OA传来的文档保护类型 + l_ProtectPassword = params[key].password; //获取OA传来的保护模式下的文档密码 + break; + case "revisionCtrl".toUpperCase(): //限制修订状态 + l_bOpenRevision = params[key].bOpenRevision; + l_bShowRevision = params[key].bShowRevision; + break; + case "buttonGroups".toUpperCase(): //按钮组合 + break; + case "docPassword".toUpperCase(): //传入打开文件的密码 + l_strDocPassword = params[key].docPassword; + break; + } + + } + + var l_Doc; + // Open方法的参数说明如下 + //Function Open(FileName, [ConfirmConversions], [ReadOnly], [AddToRecentFiles], + // [PasswordDocument], [PasswordTemplate], [Revert], [WritePasswordDocument], + // [WritePasswordTemplate], [Format], [Encoding], [Visible], + // [OpenAndRepair], [DocumentDirection], [NoEncodingDialog], [XMLTransform]) As Document + l_Doc = wps.WpsApplication().Documents.Open(TempLocalFile, false, false, false, l_strDocPassword); + + //设置文档修订状态 + DoOADocOpenRevision(l_Doc, l_bOpenRevision, l_bShowRevision); + + //打开文档后,根据保护类型设置文档保护 + if (l_ProtectType > -1) // -1 :不设置文档保护 + SetOADocProtect(l_Doc, l_ProtectType, l_ProtectPassword); + return l_Doc; +} + + +/** + * protectType: '', 文档保护模式( -1:不启用保护模式, + * 0:只允许对现有内容进行修订, + * 1:只允许添加批注, + * 2:只允许修改窗体域, + * 3:只读) + * @param {*} protectType + * @param {*} doc + */ +function SetOADocProtect(doc, protectType, ProtectPassword) { + if (!doc) return; //校验文档是否存在 + if ([0, 1, 2, 3].indexOf(protectType) !== -1) { + // 保护文档如果之前有被保护,再次保护会出问题,需要先解除保护 + doc.Unprotect(); + // ** 方法参数 + // ** Protect(Type As WdProtectionType, [NoReset], [Password], [UseIRM], [EnforceStyleLock]) + doc.Protect(protectType, false, ProtectPassword, false); + } + return; +} + + + + +/** + * 打开/关闭修订 + * @param {*} doc :传入文档对象 + * @param {*} bOpenRevision : 布尔值,是否允许打开修订模式,true:打开/false:关闭 + * @param {*} bOpenRevision : 布尔值,是否显示修订痕迹状态 + * 返回值:无 + */ +function DoOADocOpenRevision(doc, bOpenRevision, bShowRevision) { + if (!doc) return; + + doc.TrackRevisions = bOpenRevision; //如果标记对指定文档的修改,则该属性值为True + var l_v = doc.ActiveWindow.View; + l_v.ShowRevisionsAndComments = bShowRevision; //如果为True,则 WPS 显示使用“修订”功能对文档所作的修订和批注 + l_v.RevisionsBalloonShowConnectingLines = bShowRevision; //如果为 True,则 WPS 显示从文本到修订和批注气球之间的连接线 + wps.WpsApplication().CommandBars.ExecuteMso("KsoEx_RevisionCommentModify_Disable"); //去掉修改痕迹信息框中的接受修订和拒绝修订勾叉,使其不可用 + + + if (bShowRevision) { + doc.ActiveWindow.ActivePane.View.RevisionsMode = 2; //2为不支持气泡显示。 + } + + //如果关闭修订,关闭显示痕迹并将按钮至灰 + wps.ribbonUI.InvalidateControl("btnOpenRevision"); + wps.ribbonUI.InvalidateControl("btnShowRevision"); + + return; +} + + + +/** + * 描述:如何处理再次打开相同的OA文件 + * 返回值:打开的Document对象 + */ +function pReOpenOADoc(OADocURL) { + if (wps.confirm("当前环境已打开该文件,是否重新再打开一份?")) { + //如果用户选择再次打开,则用在线方式打开 + wps.WpsApplication().Documents.OpenFromUrl(OADocURL, "", ""); + } +} + +/** + * 功能说明:判断是否已存在来自OA的已打开的文档 + * @param {字符串} FileURL + */ +function pCheckIsExistOpenOADoc(FileURL) { + var l_DocCount = wps.WpsApplication().Documents.Count; + if (l_DocCount <= 0) return false; + + //轮询检查当前已打开的WPS文档中,是否存在OA相同的文件 + if (l_DocCount >= 1) { + for (var l_index = 1; l_index <= l_DocCount; l_index++) { + var l_objDoc = wps.WpsApplication().Documents.Item(l_index); + + var l_strParam = wps.PluginStorage.getItem(l_objDoc.DocID); + if (l_strParam == null) + continue; + var l_objParam = JSON.parse(l_strParam) + if (l_objParam.fileName == FileURL) { + return true; + } + } + return false; + } +} + +//Office文件打开后,设置该文件属性:从服务端来的OA文件 +function pSetOADocumentFlag(doc, params) { + if (!doc) { + return; // + } + + var l_Param = params; + l_Param.isOA = EnumOAFlag.DocFromOA; //设置OA打开文档的标志 + + l_Param.SourcePath = doc.FullName; //保存OA的原始文件路径,用于保存时分析,是否进行了另存为操作 + //console.log(l_Param.SourcePath); + + if (doc) { + var l_p = JSON.stringify(l_Param); + //将OA文档标志存入系统变量对象保存 + wps.PluginStorage.setItem(doc.DocID, l_p); + } +} + +/** + * 作用: + * @param {*} suffix :文档后缀明:.pdf 或 .uot 或 .uof + * @param {*} doc + * @param {*} uploadPath + * @param {} FieldName : 上传到服务器端的字段名称,可由OA传入的参数设置 + * + * 返回值:是否执行了上传操作,布尔值 + */ +function handleFileAndUpload(suffix, doc, uploadPath, FieldName) { + var l_strChangeFileName = ""; // 转换格式后的文件名称 + var l_strPath = ""; // 转换格式后的文件路径 + var l_FieldName = FieldName; + + if (!doc) { + return false; + } + if (!l_FieldName) { + l_FieldName = "file"; //默认情况下,设置为 file 字段名称 + } + + var l_DocSourcePath = doc.FullName; //保留当前文档明,在SaveAs使用后再保存回原来的文件明 + + //Sub ExportAsFixedFormat(OutputFileName As String, ExportFormat As WdExportFormat, + // [OpenAfterExport As Boolean = False], + // [OptimizeFor As WdExportOptimizeFor = wdExportOptimizeForPrint], + // [Range As WdExportRange = wdExportAllDocument], [From As Long = 1], + // [To As Long = 1], [Item As WdExportItem = wdExportDocumentContent], + // [IncludeDocProps As Boolean = False], [KeepIRM As Boolean = True], + // [CreateBookmarks As WdExportCreateBookmarks = wdExportCreateNoBookmarks], + // [DocStructureTags As Boolean = True], [BitmapMissingFonts As Boolean = True], + // [UseISO19005_1 As Boolean = False], [FixedFormatExtClassPtr]) + + // Const wdExportFormatPDF = 17 (&H11) + // Const wdExportFormatXPS = 18 (&H12) + // + + //根据传入的 后缀文件名称进行不同的转换文档操作 + switch (suffix.toLocaleLowerCase()) { + case '.pdf': + l_strPath = pGetValidDocTempPath(doc) + ".pdf"; //获取有效输出路径 + wps.FileSystem.Remove(l_strPath); //先删除之前可能存在的临时文件 + doc.ExportAsFixedFormat(l_strPath, wps.Enum&&wps.Enum.wdFormatPDF||17, true); //文档另存为PDF格式 + l_strChangeFileName = doc.Name.split(".")[0] + ".pdf"; + UploadFile(l_strChangeFileName, l_strPath, uploadPath, l_FieldName, OnChangeSuffixUploadSuccess, OnChangeSuffixUploadFail); + break; + case '.uof': + l_strPath = pGetValidDocTempPath(doc) + suffix; + wps.FileSystem.Remove(l_strPath); //先删除之前可能存在的临时文件 + doc.ExportAsFixedFormat(l_strPath, wps.Enum&&wps.Enum.wdFormatOpenDocumentText||23, true); //转换文件格式 + doc.SaveAs2(l_strPath); + l_strChangeFileName = doc.Name.split(".")[0] + suffix; + UploadFile(l_strChangeFileName, l_strPath, uploadPath, l_FieldName, OnChangeSuffixUploadSuccess, OnChangeSuffixUploadFail); + doc.SaveAs2(l_DocSourcePath); //保存回原来的文档内容 + break; + case '.uot': + l_strPath = pGetValidDocTempPath(doc) + suffix; + wps.FileSystem.Remove(l_strPath); //先删除之前可能存在的临时文件 + doc.ExportAsFixedFormat(l_strPath, wps.Enum&&wps.Enum.wdFormatOpenDocumentText||23, true); + doc.SaveAs2(l_strPath); + l_strChangeFileName = doc.Name.split(".")[0] + suffix; + UploadFile(l_strChangeFileName, l_strPath, uploadPath, l_FieldName, OnChangeSuffixUploadSuccess, OnChangeSuffixUploadFail); + doc.SaveAs2(l_DocSourcePath); //保存回原来的文档内容 + break; + case '.ofd': + l_strPath = pGetValidDocTempPath(doc) + suffix; + wps.FileSystem.Remove(l_strPath); //先删除之前可能存在的临时文件 + doc.ExportAsFixedFormat(l_strPath, wps.Enum&&wps.Enum.wdFormatOpenDocumentText||23, true); + doc.SaveAs2(l_strPath,102); + l_strChangeFileName = doc.Name.split(".")[0] + suffix; + UploadFile(l_strChangeFileName, l_strPath, uploadPath, l_FieldName, OnChangeSuffixUploadSuccess, OnChangeSuffixUploadFail); + doc.SaveAs2(l_DocSourcePath); //保存回原来的文档内容 + break; + default: + l_strPath = pGetValidDocTempPath(doc) + suffix; + wps.FileSystem.Remove(l_strPath); //先删除之前可能存在的临时文件 + doc.SaveAs2(l_strPath); + l_strChangeFileName = doc.Name.split(".")[0] + suffix; + UploadFile(l_strChangeFileName, l_strPath, uploadPath, l_FieldName, OnChangeSuffixUploadSuccess, OnChangeSuffixUploadFail); + doc.SaveAs2(l_DocSourcePath); //保存回原来的文档内容 + break; + } + + wps.FileSystem.Remove(l_strPath); //上载完成后,删除临时文件 + return true; +} + +/** + * 作用:获取一个有效的临时文档路径,用于保存转换格式后的文档 + * @param {*} doc + */ +function pGetValidDocTempPath(doc) { + if (!doc) { + return; + } + if (doc.Path == "") { //对于不落地文档,文档路径为空 + return wps.Env.GetTempPath()+"/"+doc.Name.split(".")[0]; + } else { + return doc.FullName.split(".")[0] + } +} + +/** + * 作用:转格式保存上传成功后,触发这个事件的回调 + * @param {} response + */ +function OnChangeSuffixUploadSuccess(response) { + l_result = handleResultBody(response); + alert("文件转格式保存成功!"); +} + +/** + * 作用:转格式保存失败,触发失败事件回调 + * @param {*} response + */ +function OnChangeSuffixUploadFail(response) { + var l_result = ""; + l_result = handleResultBody(response); + alert("保存失败" + "\n" + +"系统返回数据:" + +JSON.stringify(l_result)); +} + +/** + * 解析返回response的参数 + * @param {*} resp + * @return {*} body + */ +function handleResultBody(resp) { + var l_result = ""; + if (resp.Body) { + //解析返回response的参数 + } + return l_result; +} + +/** + * 把OA文件的当前编辑内容,自动提交到OA后台 + */ +function pAutoUploadToServer(p_Doc) { + if (!p_Doc) { + return; + } + + /** + * 参数定义:OAAsist.UploadFile(name, path, url, field, "OnSuccess", "OnFail") + * 上传一个文件到远程服务器。 + * name:为上传后的文件名称; + * path:是文件绝对路径; + * url:为上传地址; + * field:为请求中name的值; + * 最后两个参数为回调函数名称; + */ + + var l_uploadPath = GetDocParamsValue(p_Doc, constStrEnum.uploadPath); // 文件上载路径 + if (l_uploadPath == "") { + //wps.alert("系统未传入文件上载路径,不能执行上传操作!"); + return; + } + + var l_FieldName = GetDocParamsValue(p_Doc, constStrEnum.uploadFieldName); //上载到后台的字段名称 + if (l_FieldName == "") { + l_FieldName = wps.PluginStorage.getItem(constStrEnum.DefaultUploadFieldName); // 默认为‘file’ + } + + var l_UploadName = GetDocParamsValue(p_Doc, constStrEnum.uploadFileName); //设置OA传入的文件名称参数 + if (l_UploadName == "") { + l_UploadName = p_Doc.Name; //默认文件名称就是当前文件编辑名称 + } + + var l_DocPath = p_Doc.FullName; // 文件所在路径 + + if (pIsOnlineOADoc(p_Doc) == false) { + console.log("落地文档自动保存"); + //对于本地磁盘文件上传OA,先用Save方法保存后,在上传 + //设置用户保存按钮标志,避免出现禁止OA文件保存的干扰信息 + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.OADocSave); + p_Doc.Save(); //执行一次保存方法 + //设置用户保存按钮标志 + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.NoneOADocSave); + //落地文档,调用UploadFile方法上传到OA后台 + try { + //调用OA助手的上传方法 + UploadFile(l_UploadName, l_DocPath, l_uploadPath, l_FieldName, OnAutoUploadSuccess, OnAutoUploadFail); + } catch (err) { + alert("上传文件失败!请检查系统上传参数及网络环境!"); + } + } else { + console.log("不落地文档自动保存"); + // 不落地的文档,调用 Document 对象的不落地上传方法 + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.OADocSave); + try { + //调用不落地上传方法 + p_Doc.SaveAsUrl(l_UploadName, l_uploadPath, l_FieldName, "OnAutoUploadSuccess", "OnAutoUploadFail"); + } catch (err) {} + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.NoneOADocSave); + } + +} + +/** + * 作用:自动上传到OA后台成功后出发事件 + */ +function OnAutoUploadSuccess(resp) { + return; +} + +/** + * 作用:自动上传到OA后台成功后出发事件 + */ +function OnAutoUploadFail(resp) { + return; +} + +/** + * 按照定时器的时间,自动执行所有文档的自动保存事件 + */ +function OnDocSaveByAutoTimer() { + var l_Doc; + + var l_Count = 0 + var l_docCounts = wps.WpsApplication().Documents.Count; + for (l_Count = 0; l_Count < l_docCounts; l_Count++) { + l_Doc = wps.WpsApplication().Documents.Item(l_Count); + if (l_Doc) { + if (pCheckIfOADoc(l_Doc) == true) { // 是否为OA文件 + if (pISOADocReadOnly(l_Doc) == false) { // 是否为只读文档 + //执行自动上传到OA服务器端的操作 + pAutoUploadToServer(l_Doc); + //保存该文档对应的访问过程记录信息 + } + } + } + } +} + +/** + * 实现一个定时器 + */ +function OpenTimerRun(funcCallBack) { + var l_mCount = 0; //设置一个计时器,按每分钟执行一次; 10分钟后重复执行 + var l_timeID = 0; //用于保存计时器ID值 + + // 对间隔时间做处理 + var l_AutoSaveToServerTime = wps.PluginStorage.getItem(constStrEnum.AutoSaveToServerTime); + if (l_AutoSaveToServerTime == 0) { // 设置为0则不启动定时器 + l_timeID = wps.PluginStorage.getItem(constStrEnum.TempTimerID); + clearInterval(l_timeID); + return; + } else if (l_AutoSaveToServerTime < 3) { + l_AutoSaveToServerTime = 3; + } + + l_timeID = setInterval(function() { + l_mCount = l_mCount + 1; + if (l_mCount > l_AutoSaveToServerTime) { //l_AutoSaveToServerTime 值由系统配置时设定,见pInitParameters()函数 + l_mCount = 0; + funcCallBack(); //每隔l_AutoSaveToServerTime 分钟(例如10分钟)执行一次回调函数 + } + }, 60000); //60000 每隔1分钟,执行一次操作(1000*60) + + wps.PluginStorage.setItem(constStrEnum.TempTimerID, l_timeID); //保存计时器ID值 +} + +/** + * 从OA-web端点击套红头 + * params : 需要存在以下参数 + * 'insertFileUrl':'',获取红头模板接口 + * 'bkInsertFile':'' ,正文书签 + */ +function InsertRedHead(params) { + var wpsApp = wps.WpsApplication(); + var activeDoc = wpsApp.ActiveDocument; + if (!activeDoc) { + alert('文档不存在,请先新建一个文档!'); + return; + } + + var bookmark = GetParamsValue(params, constStrEnum.bkInsertFile); + var strFile = GetParamsValue(params, constStrEnum.insertFileUrl); + if (strFile == "") { + alert("未获取到传入的红头模板URL路径,不能正常套红"); + return; + } + + if (bookmark == "") { + alert("获取到传入的正文书签,不能正常套红"); + return; + } + pInsertRInedHead(activeDoc, strFile, bookmark); +} + +/** + * 套红头 + * doc :套红头的文档 + * strFile :获取红头模板接口 + * bookmark :,正文书签 + */ +function pInsertRInedHead(doc, strFile, bookmark) { + var bookMarks = doc.Bookmarks; + if (bookMarks.Item("quanwen")) { // 当前文档存在"quanwen"书签时候表示已经套过红头 + alert("当前文档已套过红头,请勿重复操作!"); + return; + } + + var wpsApp = wps.WpsApplication(); + var activeDoc = wpsApp.ActiveDocument; + var selection = wpsApp.ActiveWindow.Selection; + // 准备以非批注的模式插入红头文件(剪切/粘贴等操作会留有痕迹,故先关闭修订) + activeDoc.TrackRevisions = false; + selection.WholeStory(); //选取全文 + bookMarks.Add("quanwen", selection.Range) + selection.Cut(); + selection.InsertFile(strFile); + if (bookMarks.Exists(bookmark)) { + var bookmark1 = bookMarks.Item(bookmark); + bookmark1.Range.Select(); //获取指定书签位置 + var s = activeDoc.ActiveWindow.Selection; + s.Paste(); + } else { + alert("套红头失败,您选择的红头模板没有对应书签:" + bookmark); + } + + // 轮询插入书签 + var elements = GetDocParamsValue(doc, constStrEnum.redFileElement); + if (elements != "") { + for (var key in elements) { + console.log(key + "----" + elements[key]) + if (bookMarks.Exists(key)) { + // 直接插入 + var eleBookmark = bookMarks.Item(key); + eleBookmark.Range.Text = elements[key]; + } + } + } + + // 恢复修订模式(根据传入参数决定) + var l_revisionCtrl = GetDocParamsValue(activeDoc, constStrEnum.revisionCtrl); + activeDoc.TrackRevisions = l_revisionCtrl == "" ? false : l_revisionCtrl.bOpenRevision; + //取消WPS关闭时的提示信息 + wps.WpsApplication().DisplayAlerts = wps.Enum&&wps.Enum.wdAlertsNone||0; +} +/** + * 从OA-web端点击套红头 + * doc : 需要存在以下属性 + * 'insertFileUrl':'',获取红头模板接口 + * 'bkInsertFile':'' ,正文书签 + */ +function InsertRedHeadDoc(doc) { //插入红头 + if (!doc) { + alert('文档不存在!'); + return; + } + + var bookmark = GetDocParamsValue(doc, constStrEnum.bkInsertFile); + var strFile = GetDocParamsValue(doc, constStrEnum.insertFileUrl); + if (strFile == "") { + alert("未获取到系统传入的红头模板URL路径,不能正常套红"); + return; + } + if (bookmark == "") { + alert("套红头失败,您选择的红头模板没有正文书签!"); + return; + } + + pInsertRInedHead(doc, strFile, bookmark) +} + +/** + * 打开本地文档,并插入文档 + */ +function OpenLocalFile() { + var l_FileName = ""; + + //msoFileDialogFilePicker = 3 + var l_FileDialog = wps.WpsApplication().FileDialog(3); + if (l_FileDialog.Show()) { + l_FileName = l_FileDialog.SelectedItems; + if (l_FileName.Count > 0) { + wps.WpsApplication().Selection.InsertFile(l_FileName.Item(1)); + } + } +} + + + +/** + * 作用:OA的正文备份按钮操作功能,把OA文件备份一份到指定的OA后台copyUrl路径中 + */ +function OnUploadOABackupClicked() { + var doc = wps.WpsApplication().ActiveDocument; + if (!doc) { + alert("当前没有打开任何文档"); + return; + } + var l_copyUrl = GetDocParamsValue(doc, constStrEnum.copyUrl); + var l_uploadFieldName = GetDocParamsValue(doc, constStrEnum.uploadFieldName); + + if (!l_copyUrl) { + alert("系统未传入备份URL路径,不能执行备份!"); + return; + } + + if (!l_uploadFieldName) { + l_uploadFieldName = "file"; + } + // 默认保存为新文档,走上传文档的接口 + UploadFile(doc.Name, doc.FullName, l_copyUrl, l_uploadFieldName, OnBackupSuccess, OnBackupFail); +} + +/** + * 备份成功后的回调 + */ +function OnBackupSuccess() { + wps.alert("备份上传成功"); +} + +/** + * 备份失败后的回调 + */ +function OnBackupFail() { + wps.alert("备份失败"); +} \ No newline at end of file diff --git a/test/oaassist/WpsOAAssist/js/common/func_oastarter.js b/test/oaassist/WpsOAAssist/js/common/func_oastarter.js new file mode 100644 index 0000000..1d7e2ab --- /dev/null +++ b/test/oaassist/WpsOAAssist/js/common/func_oastarter.js @@ -0,0 +1,146 @@ +/** + * 在这个js中,集中处理来自OA的传入参数 + * + */ + +/** + * web页面调用WPS的方法入口 + * * info参数结构 + * info:[ + * { + * '方法名':'方法参数',需要执行的方法 + * }, + * ... + * ] + * @param {*} info + */ +let testFuncs=null; +function dispatcher(info) { + var funcs = info.funcs; + wps.WpsApplication().Options.UseLocalUserInfo=true//修订时,不使用登录名 + //解析参数 + /** + * 分两种情况解析: + * 1、业务系统依赖客户端返回:做同步处理,直接在for循环中返回 + */ + for (var index = 0; index < funcs.length; index++) { + var func = funcs[index]; + for (var key in func) { + if (key === "GetDocStatus") { + return GetDocStatus(func[key]) + } else if (key === "ExitWPS") { + ExitWPS(func[key]) + } + } + } + /** + * 2、业务系统不依赖客户端返回: + * 做异步处理,先返回接收状态,再在setTimeout中做打开文档的一系列业务逻辑 + */ + setTimeout(function(){ + for (var index = 0; index < funcs.length; index++) { + testFuncs=funcs; + var func = funcs[index]; + for (var key in func) { + func[key].isOA=true; + if (key === "OpenDoc") { // OpenDoc 属于普通的打开文档的操作方式,文档落地操作 + OpenDoc(func[key]); //进入打开文档处理函数 + } else if (key === "OnlineEditDoc") { //在线方式打开文档,属于文档不落地的方式打开 + OnlineEditDoc(func[key]); + } else if (key === "NewDoc") { + OpenDoc(func[key]); + } else if (key === "UseTemplate") { + OpenDoc(func[key]); + } else if (key === "InsertRedHead") { + InsertRedHead(func[key]); + } else if (key === "taskPaneBookMark"){ + taskPaneBookMark(func[key]) + } else if (key === "NewOfficialDocument"){ + return OpenDoc(func[key]) + } + } + } + },100) + return {message:"ok", app:wps.WpsApplication().Name} +} + + +/** + * 获取活动文档的状态 + */ +function GetDocStatus() { + let l_doc = wps.WpsApplication().ActiveDocument + if (l_doc && pCheckIfOADoc()) {//此方法还可根据需要进行扩展 + return{ + message: "GetDocStatus", + docstatus:{ + words: l_doc.Words.Count, + saved: l_doc.Saved, + pages: l_doc.ActiveWindow.Panes.Item(1).Pages.Count + } + } + } +} + +/** + * 关闭WPS活动文档并退出WPS进程 + */ +function ExitWPS() { + //为了接下来的用户确认操作,先将WPS界面激活显示在最前 + wps.WpsApplication().Activate(); + let l_doc = wps.WpsApplication().ActiveDocument + if (l_doc && pCheckIfOADoc()) {//此方法还可根据需要进行扩展 + l_doc.Close(); + } + if(wps.confirm("要关闭WPS软件,请确认文档都已保存。\n点击确定后关闭WPS,点击取消继续编辑。")){ + wps.WpsApplication().Quit(); + } +} + +/** + * + * @param {*} params OA端传入的参数 + */ +function OnlineEditDoc(OaParams) { + if (OaParams.fileName == "") { + NewFile(OaParams); + } else { + //OA传来下载文件的URL地址,调用openFile 方法打开 + OpenOnLineFile(OaParams); + } +} + +///打开来自OA端传递来的文档 +function OpenDoc(OaParams) { + if (OaParams.fileName == "") { + NewFile(OaParams); + } else { + //OA传来下载文件的URL地址,调用openFile 方法打开 + OpenFile(OaParams); + } +} + +function taskPaneBookMark(OaParams){ + let filePath = OaParams.fileName + if (filePath == "") + return + OpenFile(OaParams); + + //创建taskpane,只创建一次 + let id = wps.PluginStorage.getItem(constStrEnum.taskpaneid) + if (id){ + let tp = wps.GetTaskPane(id) + tp.Width = 300 + tp.Visible = true + } + else{ + let url = getHtmlURL("taskpane.html"); + let tp = wps.CreateTaskPane(url, "书签操作") + if (tp){ + tp.DockPosition = WPS_Enum.msoCTPDockPositionRight //这里可以设置taskapne是在左边还是右边 + tp.Width = 300 + tp.Visible = true + wps.PluginStorage.setItem(constStrEnum.taskpaneid, tp.ID) + } + } +} \ No newline at end of file diff --git a/test/oaassist/WpsOAAssist/js/common/func_tabcontrol.js b/test/oaassist/WpsOAAssist/js/common/func_tabcontrol.js new file mode 100644 index 0000000..0bd21d6 --- /dev/null +++ b/test/oaassist/WpsOAAssist/js/common/func_tabcontrol.js @@ -0,0 +1,1431 @@ +var EnumOAFlag = { + DocFromOA: 1, + DocFromNoOA: 0 +} + +//记录是否用户点击OA文件的保存按钮 +var EnumDocSaveFlag = { + OADocSave: 1, + NoneOADocSave: 0 +} + +//标识文档的落地模式 本地文档落地 0 ,不落地 1 +var EnumDocLandMode = { + DLM_LocalDoc: 0, + DLM_OnlineDoc: 1 +} + +//加载时会执行的方法 +function OnWPSWorkTabLoad(ribbonUI) { + wps.ribbonUI = ribbonUI; + if (typeof(wps.Enum) == "undefined") { // 如果没有内置枚举值 + wps.Enum = WPS_Enum; + } + OnJSWorkInit(); //初始化文档事件(全局参数,挂载监听事件) + // setTimeout(activeTab,2000); // 激活OA助手菜单 + OpenTimerRun(OnDocSaveByAutoTimer); //启动定时备份过程 + return true; +} + +//文档各类初始化工作(WPS Js环境) +function OnJSWorkInit() { + pInitParameters(); //OA助手环境的所有配置控制的初始化过程 + AddDocumentEvent(); //挂接文档事件处理函数 +} + +//初始化全局参数 +function pInitParameters() { + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.NoneOADocSave); //初始化,没有用户点击保存按钮 + + var l_wpsUserName = wps.WpsApplication().UserName; + wps.PluginStorage.setItem(constStrEnum.WPSInitUserName, l_wpsUserName); //在OA助手加载前,先保存用户原有的WPS应用用户名称 + + wps.PluginStorage.setItem(constStrEnum.OADocCanSaveAs, false); //默认OA文档不能另存为本地 + wps.PluginStorage.setItem(constStrEnum.AllowOADocReOpen, false); //设置是否允许来自OA的文件再次被打开 + wps.PluginStorage.setItem(constStrEnum.ShowOATabDocActive, false); //设置新打开文档是否默认显示OA助手菜单Tab 默认为false + + wps.PluginStorage.setItem(constStrEnum.DefaultUploadFieldName, "file"); //针对UploadFile方法设置上载字段名称 + + wps.PluginStorage.setItem(constStrEnum.AutoSaveToServerTime, "10"); //自动保存回OA服务端的时间间隔。如果设置0,则关闭,最小设置3分钟 + wps.PluginStorage.setItem(constStrEnum.TempTimerID, "0"); //临时值,用于保存计时器ID的临时值 + + // 以下是一些临时状态参数,用于打开文档等的状态判断 + wps.PluginStorage.setItem(constStrEnum.IsInCurrOADocOpen, false); //用于执行来自OA端的新建或打开文档时的状态 + wps.PluginStorage.setItem(constStrEnum.IsInCurrOADocSaveAs, false); //用于执行来自OA端的文档另存为本地的状态 + wps.PluginStorage.setItem(constStrEnum.RevisionEnableFlag, false) //按钮的标记控制 + wps.PluginStorage.setItem(constStrEnum.Save2OAShowConfirm, true); //弹出上传成功后的提示信息 +} + +//挂载WPS的文档事件 +function AddDocumentEvent() { + wps.ApiEvent.AddApiEventListener("WindowActivate", OnWindowActivate); + wps.ApiEvent.AddApiEventListener("DocumentBeforeSave", OnDocumentBeforeSave); + wps.ApiEvent.AddApiEventListener("DocumentBeforeClose", OnDocumentBeforeClose); + wps.ApiEvent.AddApiEventListener("DocumentAfterClose", OnDocumentAfterClose); + wps.ApiEvent.AddApiEventListener("DocumentBeforePrint", OnDocumentBeforePrint); + wps.ApiEvent.AddApiEventListener("DocumentOpen", OnDocumentOpen); + wps.ApiEvent.AddApiEventListener("DocumentNew", OnDocumentNew); + // wps.ApiEvent.AddApiEventListener("NewDocument", OnDocumentNew); + console.log("AddDocumentEvent"); +} + +/** + * 打开插入书签页面 + */ +function OnInsertBookmarkToDoc() { + if (!wps.WpsApplication().ActiveDocument) { + return; + } + OnShowDialog("selectBookmark.html", "自定义书签", 700, 440, false); +} + +/** + * 作用:打开当前文档的页面设置对话框 + */ +function OnPageSetupClicked() { + var wpsApp = wps.WpsApplication(); + var doc = wpsApp.ActiveDocument; + if (!doc) { + return; + } + wpsApp.Dialogs.Item(wps.Enum&&wps.Enum.wdDialogFilePageSetup||178).Show(); +} + +/** + * 作用:打开当前文档的打印设置对话框 + */ +function OnPrintDocBtnClicked() { + var wpsApp = wps.WpsApplication(); + var doc = wpsApp.ActiveDocument; + if (!doc) { + return; + } + wpsApp.Dialogs.Item(wps.Enum&&wps.Enum.wdDialogFilePrint||88).Show(); +} + + +/** + * 作用:接受所有修订内容 + * + */ +function OnAcceptAllRevisions() { + //获取当前文档对象 + var l_Doc = wps.WpsApplication().ActiveDocument; + if (!l_Doc) { + return; + } + if (l_Doc.Revisions.Count >= 1) { + if (!wps.confirm("目前有" + l_Doc.Revisions.Count + "个修订信息,是否全部接受?")) { + return; + } + l_Doc.AcceptAllRevisions(); + } +} + + +/** + * 作用:拒绝当前文档的所有修订内容 + */ +function OnRejectAllRevisions() { + var l_Doc = wps.WpsApplication().ActiveDocument; + if (!l_Doc) { + return; + } + if (l_Doc.Revisions.Count >= 1) { + l_Doc.RejectAllRevisions(); + } +} + + +/** + * 作用:把当前文档修订模式关闭 + */ +function OnCloseRevisions() { + //获取当前文档对象 + var l_Doc = wps.WpsApplication().ActiveDocument; + OnRevisionsSwitch(l_Doc, false); +} + + +/** + * 作用:把当前文档修订模式打开 + */ +function OnOpenRevisions() { + //获取当前文档对象 + var l_Doc = wps.WpsApplication().ActiveDocument; + OnRevisionsSwitch(l_Doc, true); +} + +function OnRevisionsSwitch(doc, openRevisions) { + if (!doc) { + return; + } + var l_activeWindow = doc.ActiveWindow; + if (l_activeWindow) { + var v = l_activeWindow.View; + if (v) { + //WPS 显示使用“修订”功能对文档所作的修订和批注 + v.ShowRevisionsAndComments = openRevisions; + //WPS 显示从文本到修订和批注气球之间的连接线 + v.RevisionsBalloonShowConnectingLines = openRevisions; + } + if (openRevisions == true) { + //去掉修改痕迹信息框中的接受修订和拒绝修订勾叉,使其不可用 + wps.WpsApplication().CommandBars.ExecuteMso("KsoEx_RevisionCommentModify_Disable"); + } + + //RevisionsMode: + //wdBalloonRevisions 0 在左边距或右边距的气球中显示修订。 + //wdInLineRevisions 1 在正文中显示修订,使用删除线表示删除,使用下划线表示插入。 + // 这是 Word 早期版本的默认设置。 + //wdMixedRevisions 2 不支持。 + doc.TrackRevisions = openRevisions; // 开关修订 + l_activeWindow.ActivePane.View.RevisionsMode = 2; //2为不支持气球显示。 + + } +} + +/** + * 作用:打开扫描仪 + */ +function OnOpenScanBtnClicked() { + var doc = wps.WpsApplication().ActiveDocument; + if (!doc) { + return; + } + //打开扫描仪 + try { + wps.WpsApplication().WordBasic.InsertImagerScan(); //打开扫描仪 + } catch (err) { + alert("打开扫描仪的过程遇到问题。"); + } +} + +/** + * 作用:在文档的当前光标处插入从前端传递来的图片 + * OA参数中 picPath 是需要插入的图片路径 + * 图片插入的默认版式是在浮于文档上方 + */ +function DoInsertPicToDoc() { + console.log("DoInsertPicToDoc..."); + + var l_doc; //文档对象 + l_doc = wps.WpsApplication().ActiveDocument; + if (!l_doc) { + return; + } + + //获取当前文档对象对应的OA参数 + var l_picPath = GetDocParamsValue(l_doc, constStrEnum.picPath); // 获取OA参数传入的图片路径 + if (l_picPath == "") { + // alert("未获取到系统传入的图片URL路径,不能正常插入图片"); + // return; + //如果没有传,则默认写一个图片地址 + l_picPath="http://127.0.0.1:3888/file/OA模板公章.png" + } + + var l_picHeight = GetDocParamsValue(l_doc, constStrEnum.picHeight); //图片高 + var l_picWidth = GetDocParamsValue(l_doc, constStrEnum.picWidth); //图片宽 + + if (l_picHeight == "") { //设定图片高度 + l_picHeight = 39.117798; //13.8mm=39.117798磅 + } + if (l_picWidth == "") { //设定图片宽度 + l_picWidth = 72; //49.7mm=140.880768磅 + } + + var l_shape = l_doc.Shapes.AddPicture(l_picPath, false, true); + l_shape.Select(); + // l_shape.WrapFormat.Type = wps.Enum&&wps.Enum.wdWrapBehind||5; //图片的默认版式为浮于文字上方,可通过此设置图片环绕模式 +} +/** + * 作用:模拟插入签章图片 + * @param {*} doc 文档对象 + * @param {*} picPath 图片路径 + * @param {*} picWidth 图片宽度 + * @param {*} picHeight 图片高度 + */ +function OnInsertPicToDoc(doc, picPath, picWidth, picHeight,callBack) { + // alert("图片路径:"+picPath); + if (!doc) { + return; + } + if (typeof picPath == "undefined" || picPath == null || picPath == "") { + alert("未获取到系统传入的图片URL路径,不能正常插入印章"); + return; + } + if (!picWidth) { //设定图片宽度 + picWidth = 95; //49.7mm=140.880768磅 + } + if (!picHeight) { //设定图片高度 + picHeight = 40; //13.8mm=39.117798磅 + } + + var selection = doc.ActiveWindow.Selection; // 活动窗口选定范围或插入点 + var pagecount = doc.BuiltInDocumentProperties.Item(wps.Enum&&wps.Enum.wdPropertyPages||14); //获取文档页数 + selection.GoTo(wps.Enum&&wps.Enum.wdGoToPage||1, wps.Enum&&wps.Enum.wdGoToPage||1, pagecount.Value); //将光标指向文档最后一页 + DownloadFile(picPath,function(url){ + selection.ParagraphFormat.LineSpacing = 12 //防止文档设置了固定行距 + var picture = selection.InlineShapes.AddPicture(url, true, true); //插入图片 + wps.FileSystem.Remove(url) //删除本地的图片 + picture.LockAspectRatio = 0; //在调整形状大小时可分别改变其高度和宽度 + picture.Height = picHeight; //设定图片高度 + picture.Width = picWidth; //设定图片宽度 + picture.LockAspectRatio = 0; + picture.Select(); //当前图片为焦点 + + //定义印章图片对象 + var seal_shape = picture.ConvertToShape(); //类型转换:嵌入型图片->粘贴版型图片 + + seal_shape.RelativeHorizontalPosition = wps.Enum&&wps.Enum.wdRelativeHorizontalPositionPage||1; + seal_shape.RelativeVerticalPosition = wps.Enum&&wps.Enum.wdRelativeVerticalPositionPage||1; + seal_shape.Left = 315; //设置指定形状或形状范围的垂直位置(以磅为单位)。 + seal_shape.Top = 630; //指定形状或形状范围的水平位置(以磅为单位)。 + callBack&&callBack() + }) + +} + + + +/** + * 作用: 把当前文档保存为其他格式的文档并上传 + * @param {*} p_FileSuffix 输出的目标格式后缀名,支持:.pdf .uof .uot .ofd + * @param {*} pShowPrompt 是否弹出用户确认框 + */ +function OnDoChangeToOtherDocFormat(p_FileSuffix, pShowPrompt) { + var l_suffix = p_FileSuffix; // params.suffix; + if (!l_suffix) { + return; + } + //获取当前执行格式转换操作的文档 + var l_doc = wps.WpsApplication().ActiveDocument; + if (!l_doc) { + return; + } + console.log(pShowPrompt) + if (typeof(pShowPrompt) == "undefined") { + pShowPrompt = true; //默认设置为弹出用户确认框 + } + //默认设置为以当前文件的显示模式输出,即当前为修订则输出带有修订痕迹的 + pDoChangeToOtherDocFormat(l_doc, l_suffix, pShowPrompt, true); +} +/** + * 作用:获取文档的Path或者临时文件路径 + * @param {*} doc + */ + function getDocSavePath(doc) { + if (!doc) { + return; + } + if (doc.Path == "") { //对于不落地文档,文档路径为空 + return wps.Env.GetTempPath(); + } else { + return doc.Path + } +} +/** + * 作用:把当前文档输出为另外的格式保存 + * @param {*} p_Doc 文档对象 + * @param {*} p_Suffix 另存为的目标文件格式 + * @param {*} pShowPrompt 是否弹出用户确认框 + * @param {*} p_ShowRevision :是否强制关闭修订,如果是False,则强制关闭痕迹显示。如果为true则不做控制输出。 + */ +function pDoChangeToOtherDocFormat(p_Doc, p_Suffix, pShowPrompt, p_ShowRevision) { + if (!p_Doc) { + return; + } + + var l_suffix = p_Suffix; + //获取该文档对应OA参数的上载路径 + var l_uploadPath = GetDocParamsValue(p_Doc, constStrEnum.uploadAppendPath); + if (l_uploadPath == "" || l_uploadPath == null) { + l_uploadPath = GetDocParamsValue(p_Doc, constStrEnum.uploadPath); + } + var l_FieldName = GetDocParamsValue(p_Doc, constStrEnum.uploadFieldName); + if (l_FieldName == "") { + l_FieldName = wps.PluginStorage.getItem(constStrEnum.DefaultUploadFieldName); //默认是'file' + } + + if (l_uploadPath == "" && pShowPrompt == true) { + alert("系统未传入有效上载文件路径!不能继续转换操作。"); //如果OA未传入上载路径,则给予提示 + return; + } + + if (pShowPrompt == true) { + if (!wps.confirm("当前文档将另存一份" + l_suffix + " 格式的副本,并上传到系统后台,请确认 ?")) { + return; + } + } + + // 先把文档输出保存为指定的文件格式,再上传到后台 + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, true); //设置一个临时变量,用于在BeforeSave事件中判断 + if (p_ShowRevision == false) { // 强制关闭痕迹显示 + var l_SourceName = p_Doc.Name; + var l_NewName=""; + var docPath=getDocSavePath(p_Doc); + if(docPath.indexOf("\\")>0){ + l_NewName = docPath + "\\B_" + p_Doc.Name; + }else{ + l_NewName = docPath + "/B_" + p_Doc.Name; + } + if(docPath.indexOf("\\")>0){ + l_SourceName = docPath + "\\" + l_SourceName; + }else{ + l_SourceName = docPath + "/" + l_SourceName; + } + + p_Doc.SaveAs2($FileName = l_NewName, $AddToRecentFiles = false); + p_Doc.SaveAs2($FileName = l_SourceName, $AddToRecentFiles = false); + //以下以隐藏模式打开另一个文档 + var l_textEncoding = wps.WpsApplication().Options.DefaultTextEncoding; //默认 936 + var l_Doc = wps.WpsApplication().Documents.Open(l_NewName, false, false, false, "", "", false, "", "", 0, l_textEncoding, false); + + l_Doc.TrackRevisions = false; //关闭修订模式 + l_Doc.ShowRevisions = false; //隐含属性,隐藏修订模式 + l_Doc.AcceptAllRevisions(); + l_Doc.Save(); + handleFileAndUpload(l_suffix, l_Doc, l_uploadPath, l_FieldName); + l_Doc.Close(); + wps.FileSystem.Remove(l_NewName); //删除临时文档 + } else { + handleFileAndUpload(l_suffix, p_Doc, l_uploadPath, l_FieldName); + } + + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, false); + + return; +} + +/** + * 把文档转换成UOT在上传 + */ +function OnDoChangeToUOF() {} + +/** + * 打开WPS云文档的入口 + */ +function pDoOpenWPSCloundDoc() { + wps.TabPages.Add("https://www.kdocs.cn"); +} + +/** + * 执行另存为本地文件操作 + */ +function OnBtnSaveAsLocalFile() { + + //初始化临时状态值 + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, false); + wps.PluginStorage.setItem(constStrEnum.IsInCurrOADocSaveAs, false); + + //检测是否有文档正在处理 + var l_doc = wps.WpsApplication().ActiveDocument; + if (!l_doc) { + alert("WPS当前没有可操作文档!"); + return; + } + + // 设置WPS文档对话框 2 FileDialogType:=msoFileDialogSaveAs + var l_ksoFileDialog = wps.WpsApplication().FileDialog(2); + l_ksoFileDialog.InitialFileName = l_doc.Name; //文档名称 + + if (l_ksoFileDialog.Show() == -1) { // -1 代表确认按钮 + //alert("确认"); + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, true); //设置保存为临时状态,在Save事件中避免OA禁止另存为对话框 + l_ksoFileDialog.Execute(); //会触发保存文档的监听函数 + + pSetNoneOADocFlag(l_doc); + + wps.ribbonUI.Invalidate(); //刷新Ribbon的状态 + + }; +} + +// +/** + * 作用:执行清稿按钮操作 + * 业务功能:清除所有修订痕迹和批注 + */ +function OnBtnClearRevDoc() { + var doc = wps.WpsApplication().ActiveDocument; + if (!doc) { + alert("尚未打开文档,请先打开文档再进行清稿操作!"); + } + + //执行清稿操作前,给用户提示 + if (!wps.confirm("清稿操作将接受所有的修订内容,关闭修订显示。请确认执行清稿操作?")) { + return; + } + + //接受所有修订 + if (doc.Revisions.Count >= 1) { + doc.AcceptAllRevisions(); + } + //去除所有批注 + if (doc.Comments.Count >= 1) { + doc.RemoveDocumentInformation(wps.Enum&&wps.Enum.wdRDIComments||1); + } + + //删除所有ink墨迹对象 + pDeleteAllInkObj(doc); + + doc.TrackRevisions = false; //关闭修订模式 + wps.ribbonUI.InvalidateControl("btnOpenRevision"); + + return; +} + +/** + * 作用:删除当前文档的所有墨迹对象 + * @param {*} p_Doc + */ +function pDeleteAllInkObj(p_Doc) { + var l_Count = 0; + var l_IsInkObjExist = true; + while (l_IsInkObjExist == true && l_Count < 20) { + l_IsInkObjExist = pDeleteInkObj(p_Doc); + l_Count++; + } + return; +} + +/** + * 删除墨迹对象 + */ +function pDeleteInkObj(p_Doc) { + var l_IsInkObjExist = false; + if (p_Doc) { + for (var l_Index = 1; l_Index <= p_Doc.Shapes.Count; l_Index++) { + var l_Item = p_Doc.Shapes.Item(l_Index); + if (l_Item.Type == 23) { + l_Item.Delete(); + //只要有一次找到Ink类型,就标识一下 + if (l_IsInkObjExist == false) { + l_IsInkObjExist = true; + } + } + } + } + return l_IsInkObjExist; +} + + +/** + * + */ +function pSaveAnotherDoc(p_Doc) { + if (!p_Doc) { + return; + } + var l_SourceDocName = p_Doc.Name; + var l_NewName = "BK_" + l_SourceDocName; + p_Doc.SaveAs2(l_NewName); + wps.WpsApplication().Documents.Open(); +} + + +//保存到OA后台服务器 +function OnBtnSaveToServer() { + // console.log('SaveToServer'); + var l_doc = wps.WpsApplication().ActiveDocument; + if (!l_doc) { + alert("空文档不能保存!"); + return; + } + + //非OA文档,不能上传到OA + if (pCheckIfOADoc() == false) { + alert("非系统打开的文档,不能直接上传到系统!"); + return; + } + + //如果是OA打开的文档,并且设置了保护的文档,则不能再上传到OA服务器 + if (pISOADocReadOnly(l_doc)) { + wps.alert("系统设置了保护的文档,不能再提交到系统后台。"); + return; + } + + /** + * 参数定义:OAAsist.UploadFile(name, path, url, field, "OnSuccess", "OnFail") + * 上传一个文件到远程服务器。 + * name:为上传后的文件名称; + * path:是文件绝对路径; + * url:为上传地址; + * field:为请求中name的值; + * 最后两个参数为回调函数名称; + */ + var l_uploadPath = GetDocParamsValue(l_doc, constStrEnum.uploadPath); // 文件上载路径 + if (l_uploadPath == "") { + wps.alert("系统未传入文件上载路径,不能执行上传操作!"); + return; + } + + var l_showConfirm = wps.PluginStorage.getItem(constStrEnum.Save2OAShowConfirm) + if (l_showConfirm) { + if (!wps.confirm("先保存文档,并开始上传到系统后台,请确认?")) { + return; + } + } + + var l_FieldName = GetDocParamsValue(l_doc, constStrEnum.uploadFieldName); //上载到后台的业务方自定义的字段名称 + if (l_FieldName == "") { + l_FieldName = wps.PluginStorage.getItem(constStrEnum.DefaultUploadFieldName); // 默认为‘file’ + } + + var l_UploadName = GetDocParamsValue(l_doc, constStrEnum.uploadFileName); //设置OA传入的文件名称参数 + if (l_UploadName == "") { + l_UploadName = l_doc.Name; //默认文件名称就是当前文件编辑名称 + } + + var l_DocPath = l_doc.FullName; // 文件所在路径 + + if (pIsOnlineOADoc(l_doc) == false) { + //对于本地磁盘文件上传OA,先用Save方法保存后,再上传 + //设置用户保存按钮标志,避免出现禁止OA文件保存的干扰信息 + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.OADocSave); + if (l_doc.Path == "") { //对于不落地文档,文档路径为空 + l_doc.SaveAs2(wps.Env.GetTempPath() + "/" + l_doc.Name, undefined, undefined, undefined, false); + } else { + l_doc.Save(); + } + //执行一次保存方法 + //设置用户保存按钮标志 + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.NoneOADocSave); + //落地文档,调用UploadFile方法上传到OA后台 + l_DocPath = l_doc.FullName; + try { + //调用OA助手的上传方法 + UploadFile(l_UploadName, l_DocPath, l_uploadPath, l_FieldName, OnUploadToServerSuccess, OnUploadToServerFail); + } catch (err) { + alert("上传文件失败!请检查系统上传参数及网络环境!"); + } + } else { + // 不落地的文档,调用 Document 对象的不落地上传方法 + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.OADocSave); + try { + //调用不落地上传方法 + l_doc.SaveAsUrl(l_UploadName, l_uploadPath, l_FieldName, "OnUploadToServerSuccess", "OnUploadToServerFail"); + } catch (err) { + alert("上传文件失败!请检查系统上传参数及网络环境,重新上传。"); + } + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.NoneOADocSave); + } + + //获取OA传入的 转其他格式上传属性 + var l_suffix = GetDocParamsValue(l_doc, constStrEnum.suffix); + if (l_suffix == "") { + console.log("上传需转换的文件后缀名错误,无法进行转换上传!"); + return; + } + + //判断是否同时上传PDF等格式到OA后台 + var l_uploadWithAppendPath = GetDocParamsValue(l_doc, constStrEnum.uploadWithAppendPath); //标识是否同时上传suffix格式的文档 + if (l_uploadWithAppendPath == "1") { + //调用转pdf格式函数,强制关闭转换修订痕迹,不弹出用户确认的对话框 + pDoChangeToOtherDocFormat(l_doc, l_suffix, false, false); + } + return; +} + + +/** + * 作用:套红头 + * 所有与OA系统相关的业务功能,都放在oabuss 子目录下 + */ +function OnInsertRedHeaderClick() { + var l_Doc = wps.WpsApplication().ActiveDocument; + if (!l_Doc) { + return; + } + var l_insertFileUrl = GetDocParamsValue(l_Doc, constStrEnum.insertFileUrl); //插入文件的位置 + var l_BkFile = GetDocParamsValue(l_Doc, constStrEnum.bkInsertFile); + if (l_BkFile == "" || l_insertFileUrl == "") { + var height = 250; + var width = 400; + OnShowDialog("redhead.html", "OA助手", width, height); + return; + } + InsertRedHeadDoc(l_Doc); +} + + +/** + * 插入时间 + * params参数结构 + * params:{ + * + * } + */ +function OnInsertDateClicked() { + var l_Doc = wps.WpsApplication().ActiveDocument; + if (l_Doc) { + //打开插入日期对话框 + wps.WpsApplication().Dialogs.Item(wps.Enum&&wps.Enum.wdDialogInsertDateTime||165).Show(); + } +} + + +/** + * 调用文件上传到OA服务端时, + * @param {*} resp + */ +function OnUploadToServerSuccess(resp) { + console.log("成功上传服务端后的回调:" + resp) + console.log(resp) + var l_doc = wps.WpsApplication().ActiveDocument; + var l_showConfirm = wps.PluginStorage.getItem(constStrEnum.Save2OAShowConfirm); + if (l_showConfirm) { + if (wps.confirm("文件上传成功!继续编辑请确认,取消关闭文档。") == false) { + if (l_doc) { + console.log("OnUploadToServerSuccess: before Close"); + l_doc.Close(-1); //保存文档后关闭 + console.log("OnUploadToServerSuccess: after Close"); + } + } + } + + var l_NofityURL = GetDocParamsValue(l_doc, constStrEnum.notifyUrl); + if (l_NofityURL != "") { + l_NofityURL = l_NofityURL.replace("{?}", "2"); //约定:参数为2则文档被成功上传 + NotifyToServer(l_NofityURL); + } +} + +function OnUploadToServerFail(resp) { + alert("文件上传失败!"); +} + +function OnbtnTabClick() { + alert("OnbtnTabClick"); +} + + + +//判断当前文档是否是OA文档 +function pCheckIfOADoc() { + var doc = wps.WpsApplication().ActiveDocument; + if (!doc) + return false; + return CheckIfDocIsOADoc(doc); +} + +//根据传入的doc对象,判断当前文档是否是OA文档 +function CheckIfDocIsOADoc(doc) { + if (!doc) { + return false; + } + + var l_isOA = GetDocParamsValue(doc, constStrEnum.isOA); + if (l_isOA == "") { + return false + }; + + return l_isOA == EnumOAFlag.DocFromOA ? true : false; +} + +//获取文件来源标识 +function pGetDocSourceLabel() { + return pCheckIfOADoc() ? "OA文件" : "非OA文件"; +} + + + +/** + * 作用:设置用户名称标签 + */ +function pSetUserNameLabelControl() { + var l_doc = wps.WpsApplication().ActiveDocument; + if (!l_doc) return ""; + + var l_strUserName = ""; + if (pCheckIfOADoc() == true) { // OA文档,获取OA用户名 + var userName = GetDocParamsValue(l_doc, constStrEnum.userName); + l_strUserName = userName == "" ? "未设置" : userName; + } else { + //非OA传来的文档,则按WPS安装后设置的用户名显示 + l_strUserName = "" + wps.PluginStorage.getItem(constStrEnum.WPSInitUserName); + } + + return l_strUserName; +} + + +/** + * 作用:判断是否是不落地文档 + * 参数:doc 文档对象 + * 返回值: 布尔值 + */ +function pIsOnlineOADoc(doc) { + var l_LandMode = GetDocParamsValue(doc, constStrEnum.OADocLandMode); //获取文档落地模式 + if (l_LandMode == "") { //用户本地打开的文档 + return false; + } + return l_LandMode == EnumDocLandMode.DLM_OnlineDoc; +} +/** + * 作用:返回OA文档落地模式标签 + */ +function pGetOADocLabel() { + var l_Doc = wps.WpsApplication().ActiveDocument; + if (!l_Doc) { + return ""; + } + + var l_strLabel = ""; //初始化 + + if (pIsOnlineOADoc(l_Doc) == true) { // 判断是否为不落地文档 + l_strLabel = "文档状态:不落地"; + } else { + l_strLabel = l_Doc.Path != "" ? "文档状态:落地" : "文档状态:未保存"; + } + + //判断OA文档是否是受保护 + if (pISOADocReadOnly(l_Doc) == true) { + l_strLabel = l_strLabel + "(保护)"; + } + return l_strLabel; +} + +//返回是否可以点击OA保存按钮的状态 +function OnSetSaveToOAEnable() { + return pCheckIfOADoc(); +} + + +/** + * 作用:根据OA传入参数,设置是否显示Ribbob按钮组 + * 参数:CtrlID 是OnGetVisible 传入的Ribbob控件的ID值 + */ +function pShowRibbonGroupByOADocParam(CtrlID) { + var l_Doc = wps.WpsApplication().ActiveDocument; + if (!l_Doc) { + return false; //如果未装入文档,则设置OA助手按钮组不可见 + } + + //获取OA传入的按钮组参数组 + var l_grpButtonParams = GetDocParamsValue(l_Doc, constStrEnum.buttonGroups); //disableBtns + l_grpButtonParams = l_grpButtonParams + "," + GetDocParamsValue(l_Doc, constStrEnum.disableBtns); + + + // 要求OA传入控制自定义按钮显示的参数为字符串 中间用 , 分隔开 + if (typeof(l_grpButtonParams) == "string") { + var l_arrayGroup = new Array(); + l_arrayGroup = l_grpButtonParams.split(","); + //console.log(l_grpButtonParams); + + // 判断当前按钮是否存在于数组 + if (l_arrayGroup.indexOf(CtrlID) >= 0) { + return false; + } + } + // 添加OA菜单判断 + if (CtrlID == "WPSWorkExtTab") { + if(wps.WpsApplication().ActiveDocument){ + let l_value=GetDocParamsValue(wps.WpsApplication().ActiveDocument,"isOA"); + return l_value?true:false; + } + var l_value = wps.PluginStorage.getItem(constStrEnum.ShowOATabDocActive); + wps.PluginStorage.setItem(constStrEnum.ShowOATabDocActive, false); //初始化临时状态变量 + console.log("菜单:" + l_value); + return l_value; + } + return true; +} + +/** + * 根据传入Document对象,获取OA传入的参数的某个Key值的Value + * @param {*} Doc + * @param {*} Key + * 返回值:返回指定 Key的 Value + */ +function GetDocParamsValue(Doc, Key) { + if (!Doc) { + return ""; + } + + var l_Params = wps.PluginStorage.getItem(Doc.DocID); + if (!l_Params) { + return ""; + } + + var l_objParams = JSON.parse(l_Params); + if (typeof(l_objParams) == "undefined") { + return ""; + } + + var l_rtnValue = l_objParams[Key]; + if (typeof(l_rtnValue) == "undefined" || l_rtnValue == null) { + return ""; + } + return l_rtnValue; +} + +/** + * 获取对象中指定属性的值 + * @param {*} params + * @param {*} Key + */ +function GetParamsValue(Params, Key) { + if (typeof(Params) == "undefined") { + return ""; + } + + var l_rtnValue = Params[Key]; + return l_rtnValue; +} + + + +/** + * 作用:插入二维码图片 + */ +function OnInsertQRCode() { + OnShowDialog("QRCode.html", "插入二维码", 400, 400); +} + + +/** + * 打开本地文档并插入到当前文档中指定位置(导入文档) + */ +function OnOpenLocalFile() { + OpenLocalFile(); +} +/** + * 插入水印 + */ +function DoInsertWaterToDoc(){ +    var app, shapeRange; +    try { +        // app = wpsFrame.Application; +        var app=wps.WpsApplication(); +        var doc = app.ActiveDocument; +        var selection = doc.ActiveWindow.Selection; +        var pageCount = app.ActiveWindow.ActivePane.Pages.Count; +        for(var i=1;i<=pageCount;i++){ +            selection.GoTo(1, 1, i); + app.ActiveWindow.ActivePane.View.SeekView=9; +            app.ActiveDocument.Sections.Item(1).Headers.Item(1).Shapes.AddTextEffect(0, "公司绝密", "华文新魏", 36, false, false, 0, 0).Select(); +            shapeRange = app.Selection.ShapeRange; +            shapeRange.TextEffect.NormalizedHeight = false; +            shapeRange.Line.Visible = false; +            shapeRange.Fill.Visible = true; +            shapeRange.Fill.Solid(); +            shapeRange.Fill.ForeColor.RGB = 12632256;       /* WdColor枚举 wdColorGray25 代表颜色值 */ +            shapeRange.Fill.Transparency = 0.5;             /* 填充透明度,值为0.0~1.0 */ +            shapeRange.LockAspectRatio = true; +            shapeRange.Height = 4.58 * 28.346; +            shapeRange.Width = 28.07 * 28.346; +            shapeRange.Rotation = 315;                      /* 图形按照Z轴旋转度数,正值为顺时针旋转,负值为逆时针旋转 */ +            shapeRange.WrapFormat.AllowOverlap = true; +            shapeRange.WrapFormat.Side = 3;                 /* WdWrapSideType枚举 wdWrapLargest 形状距离页边距最远的一侧 */ +            shapeRange.WrapFormat.Type = 3;                  +            shapeRange.RelativeHorizontalPosition = 0;       +            shapeRange.RelativeVerticalPosition = 0;         +            shapeRange.Left = '-999995';                    +            shapeRange.Top = '-999995';                      +            +        }                  /* WdShapePosition枚举 wdShapeCenter 形状的位置在中央 */ +        selection.GoTo(1, 1, 1); + app.ActiveWindow.ActivePane.View.SeekView=0; +    } catch (error) { +        alert(error.message); +    } +} + +/** + * 插入电子印章的功能 + */ +function OnInsertSeal() { + OnShowDialog("selectSeal.html", "印章", 730, 500); +} + +/** + * 导入模板到文档中 + */ +function OnImportTemplate() { + OnShowDialog("importTemplate.html", "导入模板", 560, 400); +} + + +//自定义菜单按钮的点击执行事件 +function OnAction(control) { + var eleId; + if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 + eleId = control.Id; + } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 + eleId = arguments[1].Id; + console.log(eleId) + } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 + eleId = arguments[1].Id; + } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 + eleId = arguments[2].Id; + } + switch (eleId) { + case "btnOpenWPSYUN": //打开WPS云文档入口 + pDoOpenWPSCloundDoc(); + break; + case "btnOpenLocalWPSYUN": //打开本地文档并插入到文档中 + OnOpenLocalFile(); + break; + case "WPSWorkExtTab": + OnbtnTabClick(); + break; + case "btnSaveToServer": //保存到OA服务器 + wps.PluginStorage.setItem(constStrEnum.Save2OAShowConfirm, true) + OnBtnSaveToServer(); + break; + case "btnSaveAsFile": //另存为本地文件 + OnBtnSaveAsLocalFile(); + break; + case "btnChangeToPDF": //转PDF文档并上传 + OnDoChangeToOtherDocFormat(".pdf"); + break; + case "btnChangeToUOT": //转UOF文档并上传 + OnDoChangeToOtherDocFormat(".uof"); + break; + case "btnChangeToOFD": //转OFD文档并上传 + OnDoChangeToOtherDocFormat(".ofd"); + break; + //------------------------------------ + case "btnInsertRedHeader": //插入红头 + OnInsertRedHeaderClick(); //套红头功能 + break; + case "btnUploadOABackup": //文件备份 + OnUploadOABackupClicked(); + break; + case "btnInsertSeal": //插入印章 + OnInsertSeal(); + break; + //------------------------------------ + //修订按钮组 + case "btnClearRevDoc": //执行 清稿 按钮 + OnBtnClearRevDoc(); + break; + case "btnOpenRevision": //打开修订 + { + let bFlag = wps.PluginStorage.getItem(constStrEnum.RevisionEnableFlag) + wps.PluginStorage.setItem(constStrEnum.RevisionEnableFlag, !bFlag) + //通知wps刷新以下几个按钮的状态 + wps.ribbonUI.InvalidateControl("btnOpenRevision") + wps.ribbonUI.InvalidateControl("btnCloseRevision") + OnOpenRevisions(); // + break; + } + case "btnCloseRevision": //关闭修订 + { + let bFlag = wps.PluginStorage.getItem(constStrEnum.RevisionEnableFlag) + wps.PluginStorage.setItem(constStrEnum.RevisionEnableFlag, !bFlag) + //通知wps刷新以下几个按钮的状态 + wps.ribbonUI.InvalidateControl("btnOpenRevision") + wps.ribbonUI.InvalidateControl("btnCloseRevision") + OnCloseRevisions(); + break; + } + case "btnShowRevision": + break; + case "btnAcceptAllRevisions": //接受所有修订功能 + OnAcceptAllRevisions(); + break; + case "btnRejectAllRevisions": //拒绝修订 + OnRejectAllRevisions(); + break; + //------------------------------------ + case "btnInsertPic": //插入图片 + DoInsertPicToDoc(); + break; + case "btnInsertWater": + DoInsertWaterToDoc() + case "btnInsertDate": //插入日期 + OnInsertDateClicked(); + break; + case "btnOpenScan": //打开扫描仪 + OnOpenScanBtnClicked(); + break; + case "btnPageSetup": //打开页面设置 + OnPageSetupClicked(); + break; + case "btnQRCode": //插入二维码 + OnInsertQRCode(); // + break; + case "btnPrintDOC": // 打开打印设置 + OnPrintDocBtnClicked(); + break; + case "lblDocSourceValue": //OA公文提示 + OnOADocInfo(); + break; + case "btnUserName": //点击用户 + OnUserNameSetClick(); + break; + case "btnInsertBookmark": //插入书签 + OnInsertBookmarkToDoc(); + break; + case "btnImportTemplate": //导入模板 + OnImportTemplate(); + break; + case "FileSaveAsMenu": //通过idMso进行「另存为」功能的自定义 + case "FileSaveAs": + { + if (pCheckIfOADoc()) { //文档来源是业务系统的,做自定义 + alert("这是OA文档,将Ctrl+S动作做了重定义,可以调用OA的保存文件流到业务系统的接口。") + OnBtnSaveToServer(); + } else { //本地的文档,期望不做自定义,通过转调idMso的方法实现 + wps.WpsApplication().CommandBars.ExecuteMso("FileSaveAsWordDocx"); + //此处一定不能去调用与重写idMso相同的ID,否则就是个无线递归了,即在这个场景下不可调用FileSaveAs和FileSaveAsMenu这两个方法 + } + break; + } + case "FileSave": //通过idMso进行「保存」功能的自定义 + { + if (pCheckIfOADoc()) { //文档来源是业务系统的,做自定义 + alert("这是OA文档,将Ctrl+S动作做了重定义,可以调用OA的保存文件流到业务系统的接口。") + OnBtnSaveToServer(); + } else { //本地的文档,期望不做自定义,通过转调idMso的方法实现 + // wps.WpsApplication().CommandBars.ExecuteMso("FileSave"); + wps.WpsApplication().CommandBars.ExecuteMso("SaveAll"); + //此处一定不能去调用与重写idMso相同的ID,否则就是个无线递归了,即在这个场景下不可调用FileSaveAs和FileSaveAsMenu这两个方法 + } + break; + } + case "FileNew": + case "FileNewMenu": + case "WindowNew": + case "FileNewBlankDocument": + { + if (pCheckIfOADoc()) { //文档来源是业务系统的,做自定义 + alert("这是OA文档,将Ctrl+N动作做了禁用") + } + } + break + case "ShowAlert_ContextMenuText": + { + let selectText = wps.WpsApplication().Selection.Text; + alert("您选择的内容是:\n" + selectText); + break; + } + case "btnSendMessage1": + { + /** + * 内部封装了主动响应前端发送的请求的方法 + */ + //参数自定义,这里只是负责传递参数,在WpsInvoke.RegWebNotify方法的回调函数中去做接收,自行解析参数 + let params={ + type:'executeFunc1', + message:"当前时间为:" + currentTime() + } + /** + * WebNotify: + * 参数1:发送给业务系统的消息 + * 参数2:是否将消息加入队列,是否防止丢失消息,都需要设置为true + */ + wps.OAAssist.WebNotify(JSON.stringify(params),true); //如果想传一个对象,则使用JSON.stringify方法转成对象字符串。 + break; + } + case "btnSendMessage2": + { + /** + * 内部封装了主动响应前端发送的请求的方法 + */ + let msgInfo = + { + id: 1, + name: 'kingsoft', + since: "1988" + } + //参数自定义,这里只是负责传递参数,在WpsInvoke.RegWebNotify方法的回调函数中去做接收,自行解析参数 + + let params={ + type:'executeFunc2', + message:"当前时间为:" + currentTime(), + msgInfoStr: JSON.stringify(msgInfo) + } + /** + * WebNotify: + * 参数1:发送给业务系统的消息 + * 参数2:是否将消息加入队列,是否防止丢失消息,都需要设置为true + */ + wps.OAAssist.WebNotify(JSON.stringify(params),true); //如果想传一个对象,则使用JSON.stringify方法转成对象字符串。 + break; + } + case "btnAddWebShape": + { + let l_doc = wps.WpsApplication().ActiveDocument; + l_doc.Shapes.AddWebShape("https://www.wps.cn"); + break; + } + default: + break; + } + return true; +} + +/** + * 作用:重新设置当前用户名称 + */ +function OnUserNameSetClick() { + var l_UserPageUrl = "setUserName.html" + OnShowDialog(l_UserPageUrl, "OA助手用户名称设置", 500, 300); +} +/** + * 作用:展示当前文档,被OA助手打开后的,操作记录及相关附加信息 + */ +function OnOADocInfo() { + return; +} + +/** + * 作用:自定义菜单按钮的图标 + */ +function GetImage(control) { + var eleId; + if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 + eleId = control.Id; + } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 + eleId = arguments[1].Id; + } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 + eleId = arguments[1].Id; + } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 + eleId = arguments[2].Id; + } + switch (eleId) { + case "btnOpenWPSYUN": + return "./icon/w_WPSCloud.png"; //打开WPS云文档 + case "btnOpenLocalWPSYUN": //导入文件 + return "./icon/w_ImportDoc.png" + case "btnSaveToServer": //保存到OA后台服务端 + return "./icon/w_Save.png"; + case "btnSaveAsFile": //另存为本地文件 + return "./icon/w_SaveAs.png"; + case "btnChangeToPDF": //输出为PDF格式 + return "./icon/w_PDF.png"; + case "btnChangeToUOT": // + return "./icon/w_DocUOF.png"; + case "btnChangeToOFD": //转OFD上传 + return "./icon/w_DocOFD.png"; // + case "btnInsertRedHeader": //套红头 + return "./icon/w_GovDoc.png"; + case "btnInsertSeal": //印章 + return "./icon/c_seal.png"; + case "btnClearRevDoc": //清稿 + return "./icon/w_DocClear.png" + case "btnUploadOABackup": //备份正文 + return "./icon/w_BackDoc.png"; + case "btnOpenRevision": //打开 修订 + case "btnShowRevision": // + return "./icon/w_OpenRev.png"; + case "btnCloseRevision": //关闭修订 + return "./icon/w_CloseRev.png"; + case "btnAcceptAllRevisions": // 接受修订 + return "./icon/w_AcceptRev.png"; + case "btnRejectAllRevisions": // 拒绝修订 + return "./icon/w_RejectRev.png"; + case "btnSaveAsFile": + return ""; + case "btnInsertWater": + case "btnInsertPic": //插入图片 + return "./icon/w_InsPictures.png"; + case "btnOpenScan": //打开扫描仪 + return "./icon/w_Scanner16.png"; // + case "btnPageSetup": //打开页面设置 + return "./icon/w_PageGear.png"; + case "btnInsertDate": //插入日期 + return "./icon/w_InsDate.png"; + case "btnQRCode": //二维码 + return "./icon/w_DocQr.png"; + case "btnPrintDOC": // 打印设置 + return "./icon/c_printDoc.png"; + case "btnInsertBookmark": + return "./icon/c_bookmark.png"; + case "btnImportTemplate": + return "./icon/w_ImportDoc.png"; + case "btnSendMessage1": + return "./icon/3.svg" + case "btnSendMessage2": + return "./icon/3.svg" + default: + ; + } + return "./icon/c_default.png"; +} + +function pGetOpenRevisionButtonLabel() { + return "打开修订"; +} + +function pGetShowRevisionButtonLabel() { + return "显示修订"; +} + + +//xml文件中自定义按钮的文字处理函数 +function OnGetLabel(control) { + var eleId; + if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 + eleId = control.Id; + } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 + eleId = arguments[1].Id; + } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 + eleId = arguments[1].Id; + } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 + eleId = arguments[2].Id; + } + switch (eleId) { + case "btnOpenWPSYUN": //打开WPS云文档 + return "WPS云文档"; + case "btnOpenLocalWPSYUN": //打开本地云文档目录 + return "导入文档"; + case "btnSaveAsFile": + return "另存为本地"; + case "btnChangeToPDF": //转PDF并上传 + return "转PDF上传"; + case "btnChangeToUOT": //转UOF并上传 + return "转UOF上传"; + case "btnChangeToOFD": //转OFD格式并上传 + return "转OFD上传"; + case "lblDocSourceValue": //文件来源标签: + return pGetDocSourceLabel(); + case "lblUserName": //用户名:lableControl 控件 + return "编辑人:"; //pSetUserNameLabelControl(); + case "btnUserName": + return pSetUserNameLabelControl(); + //====================================================== + case "btnInsertRedHeader": //套红头 + return "套红头"; + case "btnInsertSeal": //插入印章 + return "印章"; + case "btnUploadOABackup": //文件备份 + return "文件备份"; + //====================================================== + case "btnOpenRevision": //打开修订按钮 + return pGetOpenRevisionButtonLabel(); + case "btnShowRevision": //显示修订按钮 + return pGetShowRevisionButtonLabel(); + case "btnCloseRevision": //关闭修订按钮 + return "关闭修订"; + case "btnClearRevDoc": //显示 清稿 + return "清稿"; + case "btnAcceptAllRevisions": //显示 接受修订 + return "接受修订"; + case "btnRejectAllRevisions": //显示 拒绝修订 + return "拒绝修订"; + case "lblDocLandMode": //显示 文档落地方式 :不落地还是本地,包括是否受保护 + return pGetOADocLabel(); + //--------------------------------------------- + case "btnInsertPic": //插入图片 + return "插图片"; + case "btnInsertDate": //插入日期 + return "插日期"; + case "btnOpenScan": //打开扫描仪 + return "扫描仪"; + case "btnInsertWater": + return "插入水印" + case "btnPageSetup": //打开页面设置 + return "页面设置"; + case "btnPrintDOC": //打开页面设置 + return "打印设置"; + case "btnInsertBookmark": + return "导入书签"; + case "btnImportTemplate": + return "导入模板"; + default: + ; + } + return ""; +} + +/** + * 作用:处理Ribbon按钮的是否可显示 + * @param {*} control :Ribbon 的按钮控件 + */ +function OnGetVisible(control) { + var eleId; + if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 + eleId = control.Id; + } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 + eleId = arguments[1].Id; + } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 + eleId = arguments[1].Id; + } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 + eleId = arguments[2].Id; + } + var l_value = false; + + //关闭一些测试中的功能 + switch (eleId) { + case "lblDocLandMode": //文档落地标签 + return true; + case "btnOpenScan": + return false; + case "btnAddWebShape": + { + if (wps.WpsApplication().Build.toString().indexOf("11.1") != -1){ + return true; + } + return false; + } + break; + default: + + } + + //按照 OA文档传递过来的属性进行判断 + l_value = pShowRibbonGroupByOADocParam(eleId); + return l_value; +} + +/** + * 作用:处理Ribbon按钮的是否可用 + * @param {*} control :Ribbon 的按钮控件 + */ +function OnGetEnabled(control) { + var eleId; + if (typeof control == "object" && arguments.length == 1) { //针对Ribbon的按钮的 + eleId = control.Id; + } else if (typeof control == "undefined" && arguments.length > 1) { //针对idMso的 + eleId = arguments[1].Id; + } else if (typeof control == "boolean" && arguments.length > 1) { //针对checkbox的 + eleId = arguments[1].Id; + } else if (typeof control == "number" && arguments.length > 1) { //针对combox的 + eleId = arguments[2].Id; + } + switch (eleId) { + case "btnSaveToServer": //保存到OA服务器的相关按钮。判断,如果非OA文件,禁止点击 + case "btnChangeToPDF": //保存到PDF格式再上传 + case "btnChangeToUOT": //保存到UOT格式再上传 + case "btnChangeToOFD": //保存到OFD格式再上传 + case "SaveAll": //保存所有文档 + //以下四个idMso的控制是关于文档新建的 + case "FileNew": + case "FileNewMenu": + case "WindowNew": + case "FileNewBlankDocument": + return OnSetSaveToOAEnable(); + case "btnCloseRevision": + { + let bFlag = wps.PluginStorage.getItem(constStrEnum.RevisionEnableFlag) + return bFlag + } + case "btnOpenRevision": + { + let bFlag = wps.PluginStorage.getItem(constStrEnum.RevisionEnableFlag) + return !bFlag + } + case "PictureInsert": + return false; + case "TabInsert"://WPS自身tab:插入 + case "TabDeveloper": //WPS自身tab:开发工具 + // case "TabPageLayoutWord": //WPS自身tab:页面布局 + // case "TabReferences": //WPS自身tab:引用 + // case "TabReviewWord": //WPS自身tab:审阅 + // case "TabView": //WPS自身tab:视图 + { + if(pCheckIfOADoc()){ + return false;//如果是OA打开的文档,把这个几个tab不可用/隐藏 + }else{ + return true; + } + } + default: + ; + } + return true; +} \ No newline at end of file diff --git a/test/oaassist/WpsOAAssist/js/common/time.js b/test/oaassist/WpsOAAssist/js/common/time.js new file mode 100644 index 0000000..5981248 --- /dev/null +++ b/test/oaassist/WpsOAAssist/js/common/time.js @@ -0,0 +1,157 @@ +var MAX_DATE = 2958465 // about year 9999 +var MAX_DATE_1904 = 2957003 + +// Half a second, expressed in days +var HALF_SECOND = (1.0 / 172800.0) + +// Half a millisecond +var HALF_MILLISECOND = (1.0 / 2000.0) + +// 从 0000/1/1 到 1900/1/1 的时间序数值 +var SERIAL_BASE_NUM = 693959 + +// 从 0000/1/1 到 1904/1/1 的时间序数值 +var SERIAL_BASE_NUM_1904 = 695421 + +// 指示是否假定 1900 年为润年(兼容 Excel) +var YEAR1900_ISLEAP = 0 + +// One-based array of days in year at month start +var _afxMonthDays = + [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]; +var b1904 = false; +var bDisable1900Year = false; + +function toTime(dtSrc, b1904) { + var tmDest = {}; + var nDays = 0; // Number of days since Dec. 30, 1899 + var nDaysAbsolute = 0; // Number of days since 1/1/0 + var nSecsInDay = 0; // Time in seconds since midnight + var nMinutesInDay = 0; // Minutes in day + + var n400Years = 0; // Number of 400 year increments since 1/1/0 + var n400Century = 0; // Century within 400 year block (0,1,2 or 3) + var n4Years = 0; // Number of 4 year increments since 1/1/0 + var n4Day = 0; // Day within 4 year block + // (0 is 1/1/yr1, 1460 is 12/31/yr4) + var n4Yr = 0; // Year within 4 year block (0,1,2 or 3) + var bLeap4 = true; // true if 4 year block includes leap year + var bIs1900Year = false; // true if this year is 1900 + + var dblDate = dtSrc; // tempory serial date + + // Round to the second + if (0 == 0) + dblDate += ((dtSrc > 0.0) ? HALF_SECOND : -HALF_SECOND); + + // If a valid date, then this conversion should not overflow + nDays = Math.floor(dblDate); + + nDaysAbsolute = Math.floor(dblDate) + (b1904 ? SERIAL_BASE_NUM_1904 : SERIAL_BASE_NUM); // Add days from 1/1/0 to 12/30/1899 + + dblDate = Math.abs(dblDate); + var dblSecsInDay = (dblDate - Math.floor(dblDate)) * 86400.0; + + nSecsInDay = Math.floor(dblSecsInDay); + + // modified by tsingbo: + // Calculate the day of week (sun=0, mon=1...) + // -1 because 1/1/0 is Sat. + tmDest.tm_wday = Math.floor((nDaysAbsolute - 1) % 7); + + if (!bDisable1900Year && !b1904 && + nDaysAbsolute >= SERIAL_BASE_NUM && + nDaysAbsolute < SERIAL_BASE_NUM + 367) { + bIs1900Year = true; + n4Day = nDaysAbsolute - SERIAL_BASE_NUM; + bLeap4 = true; + n400Years = 4; + n400Century = 3; + n4Yr = 0; + } + else { + // Leap years every 4 yrs except centuries not multiples of 400. + n400Years = Math.floor(nDaysAbsolute / 146097); + + // Set nDaysAbsolute to day within 400-year block + nDaysAbsolute %= 146097; + + // -1 because first century has extra day + n400Century = Math.floor((nDaysAbsolute - 1) / 36524); + + // Non-leap century + if (n400Century != 0) { + // Set nDaysAbsolute to day within century + nDaysAbsolute = (nDaysAbsolute - 1) % 36524; + + // +1 because 1st 4 year increment has 1460 days + n4Years = Math.floor((nDaysAbsolute + 1) / 1461); + + if (n4Years != 0) + n4Day = Math.floor((nDaysAbsolute + 1) % 1461); + else { + bLeap4 = false; + n4Day = Math.floornDaysAbsolute; + } + } + else { + // Leap century - not special case! + n4Years = Math.floor(nDaysAbsolute / 1461); + n4Day = Math.floor(nDaysAbsolute % 1461); + } + + if (bLeap4) { + // -1 because first year has 366 days + n4Yr = (n4Day - 1) / 365; + + if (n4Yr != 0) + n4Day = (n4Day - 1) % 365; + } + else { + n4Yr = n4Day / 365; + n4Day %= 365; + } + } + + // n4Day is now 0-based day of year. Save 1-based day of year, year number + tmDest.tm_yday = Math.floor(n4Day) + 1; + tmDest.tm_year = Math.floor(n400Years * 400 + n400Century * 100 + n4Years * 4 + n4Yr); + + // Handle leap year: before, on, and after Feb. 29. + if (n4Yr == 0 && bLeap4) { + // Leap Year + if ((!bIs1900Year && n4Day == 59) || + (bIs1900Year && n4Day == 60)) { + /* Feb. 29 */ + tmDest.tm_mon = 2; + tmDest.tm_mday = 29; + } + else { + // Pretend it's not a leap year for month/day comp. + if (n4Day >= 60) + --n4Day; + } + } else { + // Make n4DaY a 1-based day of non-leap year and compute + // month/day for everything but Feb. 29. + if (!bIs1900Year) + ++n4Day; + + // Month number always >= n/32, so save some loop time */ + for (tmDest.tm_mon = (n4Day >> 5) + 1; + n4Day > _afxMonthDays[tmDest.tm_mon]; tmDest.tm_mon++); + + tmDest.tm_mday = Math.floor(n4Day - _afxMonthDays[tmDest.tm_mon - 1]); + } + + if (nSecsInDay == 0) + tmDest.tm_hour = tmDest.tm_min = tmDest.tm_sec = 0; + else { + tmDest.tm_sec = Math.floor(nSecsInDay % 60); + nMinutesInDay = nSecsInDay / 60; + tmDest.tm_min = Math.floor(nMinutesInDay % 60); + tmDest.tm_hour = Math.floor(nMinutesInDay / 60); + } + + return new Date(tmDest.tm_year, tmDest.tm_mon + 1, tmDest.tm_mday, tmDest.tm_mday, tmDest.tm_min, tmDest.tm_sec); +} diff --git a/test/oaassist/WpsOAAssist/js/main.js b/test/oaassist/WpsOAAssist/js/main.js new file mode 100644 index 0000000..a079b09 --- /dev/null +++ b/test/oaassist/WpsOAAssist/js/main.js @@ -0,0 +1,12 @@ +//=======================依赖的第三方库======================= +var time=new Date().getTime() +document.write(""); +document.write(""); +//======================wps api常用枚举值===================== +document.write(""); +//=======================业务代码============================ +document.write(""); +document.write(""); +document.write(""); +document.write(""); +document.write(""); \ No newline at end of file diff --git a/test/oaassist/WpsOAAssist/otherslib/lib/formdata.js b/test/oaassist/WpsOAAssist/otherslib/lib/formdata.js new file mode 100644 index 0000000..1a3e9b5 --- /dev/null +++ b/test/oaassist/WpsOAAssist/otherslib/lib/formdata.js @@ -0,0 +1,37 @@ +/** + * Emulate FormData for some browsers + * MIT License + * (c) 2010 François de Metz + */ +(function(w) { + if (w.FakeFormData) + return; + function FormData() { + this.fake = true; + this.boundary = "--------FormData" + Math.random(); + this._fields = []; + } + FormData.prototype.append = function(key, value) { + this._fields.push([key, value]); + } + FormData.prototype.toString = function() { + var boundary = this.boundary; + var body = ""; + this._fields.forEach(function(field) { + body += "--" + boundary + "\r\n"; + // file upload + if (field[1].name) { + var file = field[1]; + body += "Content-Disposition: form-data; name=\""+ field[0] +"\"; filename=\""+ file.name +"\"\r\n"; + body += "Content-Type: "+ file.type +"\r\n\r\n"; + body += file.getAsBinary() + "\r\n"; + } else { + body += "Content-Disposition: form-data; name=\""+ field[0] +"\";\r\n\r\n"; + body += field[1] + "\r\n"; + } + }); + body += "--" + boundary +"--"; + return body; + } + w.FakeFormData = FormData; +})(window); \ No newline at end of file diff --git a/test/oaassist/WpsOAAssist/otherslib/lib/jquery.min.js b/test/oaassist/WpsOAAssist/otherslib/lib/jquery.min.js new file mode 100644 index 0000000..f4c12ca --- /dev/null +++ b/test/oaassist/WpsOAAssist/otherslib/lib/jquery.min.js @@ -0,0 +1,6 @@ +/*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license +//@ sourceMappingURL=jquery-1.10.2.min.map +*/ +(function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,l=e.jQuery,u=e.$,c={},p=[],f="1.10.2",d=p.concat,h=p.push,g=p.slice,m=p.indexOf,y=c.toString,v=c.hasOwnProperty,b=f.trim,x=function(e,t){return new x.fn.init(e,t,r)},w=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=st(),k=st(),E=st(),S=!1,A=function(e,t){return e===t?(S=!0,0):0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=mt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+yt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,n,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function lt(e){return e[b]=!0,e}function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[r]]=t}function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function dt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.defaultView;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.attachEvent&&i!==i.top&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),r.getElementsByTagName=ut(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ut(function(e){return e.innerHTML="
",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ut(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=K.test(n.querySelectorAll))&&(ut(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="
a",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="
t
",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="
",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t +}({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,r=0,o=x(this),a=e.match(T)||[];while(t=a[r++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/\s*$/g,At={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X
","
"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?""!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle); +u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("" + // 默认切换到 wps + SwitchTab(0); + //demo三种模式进行切换 + envTest() //自动配置oem.ini + if(pluginsMode==1){ + installWpsAddin() //自动安装集成 + }else{ + //卸载掉publish模式 + curList=[] + installWpsAddin() + } + +} + +function IEVersion() { + var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 + var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器 + var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器 + var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1; + if (isIE) { + var reIE = new RegExp("MSIE (\\d+\\.\\d+);"); + reIE.test(userAgent); + var fIEVersion = parseFloat(RegExp["$1"]); + if (fIEVersion == 7) { + return 7; + } else if (fIEVersion == 8) { + return 8; + } else if (fIEVersion == 9) { + return 9; + } else if (fIEVersion == 10) { + return 10; + } else { + return 6; //IE版本<=7 + } + } else if (isEdge) { + return 20; //edge + } else if (isIE11) { + return 11; //IE11 + } else { + return 30; //不是ie浏览器 + } +} + +function getHttpObj() { + var httpobj = null; + if (IEVersion() < 10) { + try { + httpobj = new XDomainRequest(); + } catch (e1) { + httpobj = new createXHR(); + } + } else { + httpobj = new createXHR(); + } + return httpobj; +} +//兼容IE低版本的创建xmlhttprequest对象的方法 +function createXHR() { + if (typeof XMLHttpRequest != 'undefined') { //兼容高版本浏览器 + return new XMLHttpRequest(); + } else if (typeof ActiveXObject != 'undefined') { //IE6 采用 ActiveXObject, 兼容IE6 + var versions = [ //由于MSXML库有3个版本,因此都要考虑 + 'MSXML2.XMLHttp.6.0', + 'MSXML2.XMLHttp.3.0', + 'MSXML2.XMLHttp' + ]; + + for (var i = 0; i < versions.length; i++) { + try { + return new ActiveXObject(versions[i]); + } catch (e) { + //跳过 + } + } + } else { + throw new Error('您的浏览器不支持XHR对象'); + } +} \ No newline at end of file diff --git a/test/oaassist/server/wwwroot/resource/js/et.js b/test/oaassist/server/wwwroot/resource/js/et.js new file mode 100644 index 0000000..f9e7842 --- /dev/null +++ b/test/oaassist/server/wwwroot/resource/js/et.js @@ -0,0 +1,237 @@ +var _et = {} + +var pluginsMode = location.search.split("=")[1];//截取url中的参数值 +var pluginType = WpsInvoke.ClientType.et//加载项类型wps,et,wpp +var pluginName = "EtOAAssist";//加载项名称 +var wpsClient = new WpsClient(pluginType);//初始化一个多进程对象,多进程时才需要 +var clientStr = pluginName + pluginType + "ClientId" +//单进程封装开始 +/** + * 此方法是根据wps_sdk.js做的调用方法封装 + * 可参照此定义 + * @param {*} funcs 这是在WPS加载项内部定义的方法,采用JSON格式(先方法名,再参数) + * @param {*} front 控制着通过页面执行WPS加载项方法,WPS的界面是否在执行时在前台显示 + * @param {*} jsPluginsXml 指定一个新的WPS加载项配置文件的地址,动态传递jsplugins.xml模式,例如:http://127.0.0.1:3888/jsplugins.xml + * @param {*} isSilent 隐藏打开WPS,如果需要隐藏,那么需要传递front参数为false + */ + + +function _WpsInvoke(funcs, front, jsPluginsXml,isSilent) { + var info = {}; + info.funcs = funcs; + if(isSilent){//隐藏启动时,front必须为false + front=false; + } + /** + * 下面函数为调起WPS,并且执行加载项WpsOAAssist中的函数dispatcher,该函数的参数为业务系统传递过去的info + */ + if (pluginsMode != 2) {//单进程 + singleInvoke(info,front,jsPluginsXml,isSilent) + } else {//多进程 + multInvoke(info,front,jsPluginsXml,isSilent) + } + +} + +//单进程 +function singleInvoke(info,front,jsPluginsXml,isSilent){ + WpsInvoke.InvokeAsHttp(pluginType, // 组件类型 + pluginName, // 插件名,与wps客户端加载的加载的插件名对应 + "dispatcher", // 插件方法入口,与wps客户端加载的加载的插件代码对应,详细见插件代码 + info, // 传递给插件的数据 + function (result) { // 调用回调,status为0为成功,其他是错误 + if (result.status) { + if (result.status == 100) { + WpsInvoke.AuthHttpesCert('请在稍后打开的网页中,点击"高级" => "继续前往",完成授权。') + return; + } + alert(result.message) + + } else { + console.log(result.response) + } + }, + front, + jsPluginsXml, + isSilent) + + /** + * 接受WPS加载项发送的消息 + * 接收消息:WpsInvoke.RegWebNotify(type,name,callback) + * WPS客户端返回消息: wps.OAAssist.WebNotify(message) + * @param {*} type 加载项对应的插件类型 + * @param {*} name 加载项对应的名字 + * @param {func} callback 接收到WPS客户端的消息后的回调函数,参数为接受到的数据 + */ + WpsInvoke.RegWebNotify(pluginType, pluginName, handleOaMessage) +} +//多进程 +function multInvoke(info,front,jsPluginsXml,isSilent){ + wpsClient.jsPluginsXml = jsPluginsXml ? jsPluginsXml : "https://127.0.0.1:3888/jsplugins.xml"; + if (localStorage.getItem(clientStr)) { + wpsClient.clientId = localStorage.getItem(clientStr) + } + if(isSilent){ + wpsClient.StartWpsInSilentMode(pluginName,function(){//隐藏启动后的回调函数 + mult(info,front) + }) + }else{ + mult(info,front) + } + wpsClient.onMessage = handleOaMessage +} +//多进程二次封装 +function mult(info,front){ + wpsClient.InvokeAsHttp( + pluginName, // 插件名,与wps客户端加载的加载的插件名对应 + "dispatcher", // 插件方法入口,与wps客户端加载的加载的插件代码对应,详细见插件代码 + info, // 传递给插件的数据         + function (result) { // 调用回调,status为0为成功,其他是错误 + if (wpsClient.clientId) { + localStorage.setItem(clientStr, wpsClient.clientId) + } + if (result.status !== 0) { + console.log(result) + if (result.message == '{\"data\": \"Failed to send message to WPS.\"}') { + wpsClient.IsClientRunning(function (status) { + console.log(status) + if (status.response == "Client is running.") + alert("任务发送失败,WPS 正在执行其他任务,请前往WPS完成当前任务") + else { + wpsClient.clientId = ""; + wpsClient.notifyRegsitered = false; + localStorage.setItem(clientStr, "") + mult(info) + } + }) + return; + } + else if (result.status == 100) { + // WpsInvoke.AuthHttpesCert('请在稍后打开的网页中,点击"高级" => "继续前往",完成授权。') + return; + } + alert(result.message) + } else { + console.log(result.response) + } + }, + front) +} + +function handleOaMessage(data) { + console.log(data) +} +function GetUploadPath() { + var url = document.location.host; + return document.location.protocol + "//" + url + "/Upload"; +} + +function GetDemoPath(fileName) { + + var url = document.location.host; + return document.location.protocol + "//" + url + "/file/" + fileName; +} + +function newDoc() { + _WpsInvoke([{ + "OpenDoc": { + showButton: "btnSaveFile;btnSaveAsLocal" + } + }]) +} + +_et['newDoc'] = { + action: newDoc, + code: _WpsInvoke.toString() + "\n\n" + newDoc.toString(), + detail: "\n\ + 说明:\n\ + 点击按钮,打开表格组件后,新建一个空白表格文档\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动表格组件,调用oaassist插件,执行插件中的js函数OpenDoc,不带文档路径则默认新建一个空白表格文档\n\ + funcs参数说明:\n\ + OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ + showButton 要显示的按钮\n\ +" +} + +function openDoc() { + var filePath = prompt("请输入打开文件路径(本地或是url):", GetDemoPath("样章.xlsx")) + var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()) + + _WpsInvoke([{ + "OpenDoc": { + "docId": "123", // 文档ID + "uploadPath": uploadPath, // 保存文档上传接口 + "fileName": filePath, + showButton: "btnSaveFile;btnSaveAsLocal" + } + }]) +} + +_et['openDoc'] = { + action: openDoc, + code: _WpsInvoke.toString() + "\n\n" + openDoc.toString(), + detail: "\n\ + 说明:\n\ + 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ + 打开表格组件后,将根据文档路径下载并打开对应的文档,保存将自动上传指定服务器地址\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动表格组件,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ + docId 文档ID,OA助手用以标记文档的信息,以区分其他文档\n\ + uploadPath 保存文档上传接口\n\ + fileName 打开的文档路径\n\ + showButton 要显示的按钮\n\ +" +} + +function onlineEditDoc() { + var filePath = prompt("请输入打开文件路径(本地或是url):", GetDemoPath("样章.xlsx")) + var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()) + + _WpsInvoke([{ + "OnlineEditDoc": { + "docId": "123", // 文档ID + "uploadPath": uploadPath, // 保存文档上传接口 + "fileName": filePath, + showButton: "btnSaveFile" + } + }]) +} + +_et['onlineEditDoc'] = { + action: onlineEditDoc, + code: _WpsInvoke.toString() + "\n\n" + onlineEditDoc.toString(), + detail: "\n\ + 说明:\n\ + 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ + 打开演示后,将根据文档路径下载并打开对应的文档,保存将自动上传指定服务器地址\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动演示组件,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OnlineEditDoc方法对应于OA助手dispatcher支持的方法名\n\ + docId 文档ID,OA助手用以标记文档的信息,以区分其他文档\n\ + uploadPath 保存文档上传接口\n\ + fileName 打开的文档路径\n\ + showButton 要显示的按钮\n\ +" +} + +window.onload = function () { + var btns = document.getElementsByClassName("btn"); + for (var i = 0; i < btns.length; i++) { + btns[i].onclick = function (event) { + document.getElementById("blockFunc").style.visibility = "visible"; + var btn2 = document.getElementById("demoBtn"); + btn2.innerText = this.innerText; + document.getElementById("codeDes").innerText = _et[this.id].detail.toString(); + document.getElementById("code").innerText = _et[this.id].code.toString(); + document.getElementById("demoBtn").onclick = _et[this.id].action; + hljs.highlightBlock(document.getElementById("code")); + } + } +} \ No newline at end of file diff --git a/test/oaassist/server/wwwroot/resource/js/utils/json2.js b/test/oaassist/server/wwwroot/resource/js/utils/json2.js new file mode 100644 index 0000000..7c00298 --- /dev/null +++ b/test/oaassist/server/wwwroot/resource/js/utils/json2.js @@ -0,0 +1,433 @@ +// json2.js +// 2017-06-12 +// Public Domain. +// NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +// USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO +// NOT CONTROL. +// This file creates a global JSON object containing two methods: stringify +// and parse. This file provides the ES5 JSON capability to ES3 systems. +// If a project might run on IE8 or earlier, then this file should be included. +// This file does nothing on ES5 systems. +// JSON.stringify(value, replacer, space) +// value any JavaScript value, usually an object or array. +// replacer an optional parameter that determines how object +// values are stringified for objects. It can be a +// function or an array of strings. +// space an optional parameter that specifies the indentation +// of nested structures. If it is omitted, the text will +// be packed without extra whitespace. If it is a number, +// it will specify the number of spaces to indent at each +// level. If it is a string (such as "\t" or " "), +// it contains the characters used to indent at each level. +// This method produces a JSON text from a JavaScript value. +// When an object value is found, if the object contains a toJSON +// method, its toJSON method will be called and the result will be +// stringified. A toJSON method does not serialize: it returns the +// value represented by the name/value pair that should be serialized, +// or undefined if nothing should be serialized. The toJSON method +// will be passed the key associated with the value, and this will be +// bound to the value. +// For example, this would serialize Dates as ISO strings. +// Date.prototype.toJSON = function (key) { +// function f(n) { +// // Format integers to have at least two digits. +// return (n < 10) +// ? "0" + n +// : n; +// } +// return this.getUTCFullYear() + "-" + +// f(this.getUTCMonth() + 1) + "-" + +// f(this.getUTCDate()) + "T" + +// f(this.getUTCHours()) + ":" + +// f(this.getUTCMinutes()) + ":" + +// f(this.getUTCSeconds()) + "Z"; +// }; +// You can provide an optional replacer method. It will be passed the +// key and value of each member, with this bound to the containing +// object. The value that is returned from your method will be +// serialized. If your method returns undefined, then the member will +// be excluded from the serialization. +// If the replacer parameter is an array of strings, then it will be +// used to select the members to be serialized. It filters the results +// such that only members with keys listed in the replacer array are +// stringified. +// Values that do not have JSON representations, such as undefined or +// functions, will not be serialized. Such values in objects will be +// dropped; in arrays they will be replaced with null. You can use +// a replacer function to replace those with JSON values. +// JSON.stringify(undefined) returns undefined. +// The optional space parameter produces a stringification of the +// value that is filled with line breaks and indentation to make it +// easier to read. +// If the space parameter is a non-empty string, then that string will +// be used for indentation. If the space parameter is a number, then +// the indentation will be that many spaces. +// Example: +// text = JSON.stringify(["e", {pluribus: "unum"}]); +// // text is '["e",{"pluribus":"unum"}]' +// text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t"); +// // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' +// text = JSON.stringify([new Date()], function (key, value) { +// return this[key] instanceof Date +// ? "Date(" + this[key] + ")" +// : value; +// }); +// // text is '["Date(---current time---)"]' +// JSON.parse(text, reviver) +// This method parses a JSON text to produce an object or array. +// It can throw a SyntaxError exception. +// The optional reviver parameter is a function that can filter and +// transform the results. It receives each of the keys and values, +// and its return value is used instead of the original value. +// If it returns what it received, then the structure is not modified. +// If it returns undefined then the member is deleted. +// Example: +// // Parse the text. Values that look like ISO date strings will +// // be converted to Date objects. +// myData = JSON.parse(text, function (key, value) { +// var a; +// if (typeof value === "string") { +// a = +// /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); +// if (a) { +// return new Date(Date.UTC( +// +a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6] +// )); +// } +// return value; +// } +// }); +// myData = JSON.parse( +// "[\"Date(09/09/2001)\"]", +// function (key, value) { +// var d; +// if ( +// typeof value === "string" +// && value.slice(0, 5) === "Date(" +// && value.slice(-1) === ")" +// ) { +// d = new Date(value.slice(5, -1)); +// if (d) { +// return d; +// } +// } +// return value; +// } +// ); +// This is a reference implementation. You are free to copy, modify, or +// redistribute. +/*jslint +eval, for, this +*/ +/*property +JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, +getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, +lastIndex, length, parse, prototype, push, replace, slice, stringify, +test, toJSON, toString, valueOf +*/ +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. +if (typeof JSON !== "object") { + JSON = {}; +} +(function () { + "use strict"; + var rx_one = /^[\],:{}\s]*$/; + var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g; + var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; + var rx_four = /(?:^|:|,)(?:\s*\[)+/g; + var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + + function f(n) { + // Format integers to have at least two digits. + return (n < 10) ? + "0" + n : + n; + } + + function this_value() { + return this.valueOf(); + } + if (typeof Date.prototype.toJSON !== "function") { + Date.prototype.toJSON = function () { + return isFinite(this.valueOf()) ? + ( + this.getUTCFullYear() + + "-" + + f(this.getUTCMonth() + 1) + + "-" + + f(this.getUTCDate()) + + "T" + + f(this.getUTCHours()) + + ":" + + f(this.getUTCMinutes()) + + ":" + + f(this.getUTCSeconds()) + + "Z" + ) : + null; + }; + Boolean.prototype.toJSON = this_value; + Number.prototype.toJSON = this_value; + String.prototype.toJSON = this_value; + } + var gap; + var indent; + var meta; + var rep; + + function quote(string) { + // If the string contains no control characters, no quote characters, and no + // backslash characters, then we can safely slap some quotes around it. + // Otherwise we must also replace the offending characters with safe escape + // sequences. + rx_escapable.lastIndex = 0; + return rx_escapable.test(string) ? + "\"" + string.replace(rx_escapable, function (a) { + var c = meta[a]; + return typeof c === "string" ? + c : + "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4); + }) + "\"" : + "\"" + string + "\""; + } + + function str(key, holder) { + // Produce a string from holder[key]. + var i; // The loop counter. + var k; // The member key. + var v; // The member value. + var length; + var mind = gap; + var partial; + var value = holder[key]; + // If the value has a toJSON method, call it to obtain a replacement value. + if ( + value && + typeof value === "object" && + typeof value.toJSON === "function" + ) { + value = value.toJSON(key); + } + // If we were called with a replacer function, then call the replacer to + // obtain a replacement value. + if (typeof rep === "function") { + value = rep.call(holder, key, value); + } + // What happens next depends on the value's type. + switch (typeof value) { + case "string": + return quote(value); + case "number": + // JSON numbers must be finite. Encode non-finite numbers as null. + return (isFinite(value)) ? + String(value) : + "null"; + case "boolean": + case "null": + // If the value is a boolean or null, convert it to a string. Note: + // typeof null does not produce "null". The case is included here in + // the remote chance that this gets fixed someday. + return String(value); + // If the type is "object", we might be dealing with an object or an array or + // null. + case "object": + // Due to a specification blunder in ECMAScript, typeof null is "object", + // so watch out for that case. + if (!value) { + return "null"; + } + // Make an array to hold the partial results of stringifying this object value. + gap += indent; + partial = []; + // Is the value an array? + if (Object.prototype.toString.apply(value) === "[object Array]") { + // The value is an array. Stringify every element. Use null as a placeholder + // for non-JSON values. + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || "null"; + } + // Join all of the elements together, separated with commas, and wrap them in + // brackets. + v = partial.length === 0 ? + "[]" : + gap ? + ( + "[\n" + + gap + + partial.join(",\n" + gap) + + "\n" + + mind + + "]" + ) : + "[" + partial.join(",") + "]"; + gap = mind; + return v; + } + // If the replacer is an array, use it to select the members to be stringified. + if (rep && typeof rep === "object") { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === "string") { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + ( + (gap) ? + ": " : + ":" + ) + v); + } + } + } + } else { + // Otherwise, iterate through all of the keys in the object. + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + ( + (gap) ? + ": " : + ":" + ) + v); + } + } + } + } + // Join all of the member texts together, separated with commas, + // and wrap them in braces. + v = partial.length === 0 ? + "{}" : + gap ? + "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}" : + "{" + partial.join(",") + "}"; + gap = mind; + return v; + } + } + // If the JSON object does not yet have a stringify method, give it one. + if (typeof JSON.stringify !== "function") { + meta = { // table of character substitutions + "\b": "\\b", + "\t": "\\t", + "\n": "\\n", + "\f": "\\f", + "\r": "\\r", + "\"": "\\\"", + "\\": "\\\\" + }; + JSON.stringify = function (value, replacer, space) { + // The stringify method takes a value and an optional replacer, and an optional + // space parameter, and returns a JSON text. The replacer can be a function + // that can replace values, or an array of strings that will select the keys. + // A default replacer method can be provided. Use of the space parameter can + // produce text that is more easily readable. + var i; + gap = ""; + indent = ""; + // If the space parameter is a number, make an indent string containing that + // many spaces. + if (typeof space === "number") { + for (i = 0; i < space; i += 1) { + indent += " "; + } + // If the space parameter is a string, it will be used as the indent string. + } else if (typeof space === "string") { + indent = space; + } + // If there is a replacer, it must be a function or an array. + // Otherwise, throw an error. + rep = replacer; + if (replacer && typeof replacer !== "function" && ( + typeof replacer !== "object" || + typeof replacer.length !== "number" + )) { + throw new Error("JSON.stringify"); + } + // Make a fake root object containing our value under the key of "". + // Return the result of stringifying the value. + return str("", { + "": value + }); + }; + } + // If the JSON object does not yet have a parse method, give it one. + if (typeof JSON.parse !== "function") { + JSON.parse = function (text, reviver) { + // The parse method takes a text and an optional reviver function, and returns + // a JavaScript value if the text is a valid JSON text. + var j; + + function walk(holder, key) { + // The walk method is used to recursively walk the resulting structure so + // that modifications can be made. + var k; + var v; + var value = holder[key]; + if (value && typeof value === "object") { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + // Parsing happens in four stages. In the first stage, we replace certain + // Unicode characters with escape sequences. JavaScript handles many characters + // incorrectly, either silently deleting them, or treating them as line endings. + text = String(text); + rx_dangerous.lastIndex = 0; + if (rx_dangerous.test(text)) { + text = text.replace(rx_dangerous, function (a) { + return ( + "\\u" + + ("0000" + a.charCodeAt(0).toString(16)).slice(-4) + ); + }); + } + // In the second stage, we run the text against regular expressions that look + // for non-JSON patterns. We are especially concerned with "()" and "new" + // because they can cause invocation, and "=" because it can cause mutation. + // But just to be safe, we want to reject all unexpected forms. + // We split the second stage into 4 regexp operations in order to work around + // crippling inefficiencies in IE's and Safari's regexp engines. First we + // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we + // replace all simple value tokens with "]" characters. Third, we delete all + // open brackets that follow a colon or comma or that begin the text. Finally, + // we look to see that the remaining characters are only whitespace or "]" or + // "," or ":" or "{" or "}". If that is so, then the text is safe for eval. + if ( + rx_one.test( + text + .replace(rx_two, "@") + .replace(rx_three, "]") + .replace(rx_four, "") + ) + ) { + // In the third stage we use the eval function to compile the text into a + // JavaScript structure. The "{" operator is subject to a syntactic ambiguity + // in JavaScript: it can begin a block or an object literal. We wrap the text + // in parens to eliminate the ambiguity. + j = eval("(" + text + ")"); + // In the optional fourth stage, we recursively walk the new structure, passing + // each name/value pair to a reviver function for possible transformation. + return (typeof reviver === "function") ? + walk({ + "": j + }, "") : + j; + } + // If the text is not JSON parseable, then a SyntaxError is thrown. + throw new SyntaxError("JSON.parse"); + }; + } +}()); \ No newline at end of file diff --git a/test/oaassist/server/wwwroot/resource/js/wpp.js b/test/oaassist/server/wwwroot/resource/js/wpp.js new file mode 100644 index 0000000..c818825 --- /dev/null +++ b/test/oaassist/server/wwwroot/resource/js/wpp.js @@ -0,0 +1,238 @@ +var _wpp = {} + +var pluginsMode = location.search.split("=")[1];//截取url中的参数值 +var pluginType = WpsInvoke.ClientType.wpp//加载项类型wps,et,wpp +var pluginName = "WppOAAssist";//加载项名称 +var wpsClient = new WpsClient(pluginType);//初始化一个多进程对象,多进程时才需要 +var clientStr = pluginName + pluginType + "ClientId" +//单进程封装开始 +/** + * 此方法是根据wps_sdk.js做的调用方法封装 + * 可参照此定义 + * @param {*} funcs 这是在WPS加载项内部定义的方法,采用JSON格式(先方法名,再参数) + * @param {*} front 控制着通过页面执行WPS加载项方法,WPS的界面是否在执行时在前台显示 + * @param {*} jsPluginsXml 指定一个新的WPS加载项配置文件的地址,动态传递jsplugins.xml模式,例如:http://127.0.0.1:3888/jsplugins.xml + * @param {*} isSilent 隐藏打开WPS,如果需要隐藏,那么需要传递front参数为false + */ + + +function _WpsInvoke(funcs, front, jsPluginsXml,isSilent) { + var info = {}; + info.funcs = funcs; + if(isSilent){//隐藏启动时,front必须为false + front=false; + } + /** + * 下面函数为调起WPS,并且执行加载项WpsOAAssist中的函数dispatcher,该函数的参数为业务系统传递过去的info + */ + if (pluginsMode != 2) {//单进程 + singleInvoke(info,front,jsPluginsXml,isSilent) + } else {//多进程 + multInvoke(info,front,jsPluginsXml,isSilent) + } + +} + +//单进程 +function singleInvoke(info,front,jsPluginsXml,isSilent){ + WpsInvoke.InvokeAsHttp(pluginType, // 组件类型 + pluginName, // 插件名,与wps客户端加载的加载的插件名对应 + "dispatcher", // 插件方法入口,与wps客户端加载的加载的插件代码对应,详细见插件代码 + info, // 传递给插件的数据 + function (result) { // 调用回调,status为0为成功,其他是错误 + if (result.status) { + if (result.status == 100) { + WpsInvoke.AuthHttpesCert('请在稍后打开的网页中,点击"高级" => "继续前往",完成授权。') + return; + } + alert(result.message) + + } else { + console.log(result.response) + } + }, + front, + jsPluginsXml, + isSilent) + + /** + * 接受WPS加载项发送的消息 + * 接收消息:WpsInvoke.RegWebNotify(type,name,callback) + * WPS客户端返回消息: wps.OAAssist.WebNotify(message) + * @param {*} type 加载项对应的插件类型 + * @param {*} name 加载项对应的名字 + * @param {func} callback 接收到WPS客户端的消息后的回调函数,参数为接受到的数据 + */ + WpsInvoke.RegWebNotify(pluginType, pluginName, handleOaMessage) +} +//多进程 +function multInvoke(info,front,jsPluginsXml,isSilent){ + wpsClient.jsPluginsXml = jsPluginsXml ? jsPluginsXml : "https://127.0.0.1:3888/jsplugins.xml"; + if (localStorage.getItem(clientStr)) { + wpsClient.clientId = localStorage.getItem(clientStr) + } + if(isSilent){ + wpsClient.StartWpsInSilentMode(pluginName,function(){//隐藏启动后的回调函数 + mult(info,front) + }) + }else{ + mult(info,front) + } + wpsClient.onMessage = handleOaMessage +} +//多进程二次封装 +function mult(info,front){ + wpsClient.InvokeAsHttp( + pluginName, // 插件名,与wps客户端加载的加载的插件名对应 + "dispatcher", // 插件方法入口,与wps客户端加载的加载的插件代码对应,详细见插件代码 + info, // 传递给插件的数据         + function (result) { // 调用回调,status为0为成功,其他是错误 + if (wpsClient.clientId) { + localStorage.setItem(clientStr, wpsClient.clientId) + } + if (result.status !== 0) { + console.log(result) + if (result.message == '{\"data\": \"Failed to send message to WPS.\"}') { + wpsClient.IsClientRunning(function (status) { + console.log(status) + if (status.response == "Client is running.") + alert("任务发送失败,WPS 正在执行其他任务,请前往WPS完成当前任务") + else { + wpsClient.clientId = ""; + wpsClient.notifyRegsitered = false; + localStorage.setItem(clientStr, "") + mult(info) + } + }) + return; + } + else if (result.status == 100) { + // WpsInvoke.AuthHttpesCert('请在稍后打开的网页中,点击"高级" => "继续前往",完成授权。') + return; + } + alert(result.message) + } else { + console.log(result.response) + } + }, + front) +} +function handleOaMessage(data) { + console.log(data) +} +function GetDemoPath(fileName) { + + var url = document.location.host; + return document.location.protocol + "//" + url + "/file/" + fileName; +} + +function GetUploadPath() { + var url = document.location.host; + return document.location.protocol + "//" + url + "/Upload"; +} + +function newDoc() { + _WpsInvoke([{ + "OpenDoc": { + showButton: "btnSaveFile;btnSaveAsLocal" + } + }]) +} + +_wpp['newDoc'] = { + action: newDoc, + code: _WpsInvoke.toString() + "\n\n" + newDoc.toString(), + detail: "\n\ + 说明:\n\ + 点击按钮,打开演示组件后,新建一个空白演示文档\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动演示组件,调用oaassist插件,执行插件中的js函数OpenDoc,不带文档路径则默认新建一个空白演示文档\n\ + funcs参数说明:\n\ + OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ + showButton 要显示的按钮\n\ +" +} + +function openDoc() { + var filePath = prompt("请输入打开文件路径(本地或是url):", GetDemoPath("样章.pptx")) + var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()) + + _WpsInvoke([{ + "OpenDoc": { + "docId": "123", // 文档ID + "uploadPath": uploadPath, // 保存文档上传接口 + "fileName": filePath, + showButton: "btnSaveFile;btnSaveAsLocal" + } + }]) +} + +_wpp['openDoc'] = { + action: openDoc, + code: _WpsInvoke.toString() + "\n\n" + openDoc.toString(), + detail: "\n\ + 说明:\n\ + 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ + 打开演示后,将根据文档路径下载并打开对应的文档,保存将自动上传指定服务器地址\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动演示组件,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ + docId 文档ID,OA助手用以标记文档的信息,以区分其他文档\n\ + uploadPath 保存文档上传接口\n\ + fileName 打开的文档路径\n\ + showButton 要显示的按钮\n\ +" +} + +function onlineEditDoc() { + var filePath = prompt("请输入打开文件路径(本地或是url):", GetDemoPath("样章.pptx")) + var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()) + + _WpsInvoke([{ + "OnlineEditDoc": { + "docId": "123", // 文档ID + "uploadPath": uploadPath, // 保存文档上传接口 + "fileName": filePath, + showButton: "btnSaveFile;btnSaveAsLocal" + } + }]) +} + +_wpp['onlineEditDoc'] = { + action: onlineEditDoc, + code: _WpsInvoke.toString() + "\n\n" + onlineEditDoc.toString(), + detail: "\n\ + 说明:\n\ + 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ + 打开演示后,将根据文档路径下载并打开对应的文档,保存将自动上传指定服务器地址\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动演示组件,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OnlineEditDoc方法对应于OA助手dispatcher支持的方法名\n\ + docId 文档ID,OA助手用以标记文档的信息,以区分其他文档\n\ + uploadPath 保存文档上传接口\n\ + fileName 打开的文档路径\n\ + showButton 要显示的按钮\n\ +" +} + +window.onload = function () { + var btns = document.getElementsByClassName("btn"); + + for (var i = 0; i < btns.length; i++) { + btns[i].onclick = function (event) { + document.getElementById("blockFunc").style.visibility = "visible"; + var btn2 = document.getElementById("demoBtn"); + btn2.innerText = this.innerText; + document.getElementById("codeDes").innerText = _wpp[this.id].detail.toString() + document.getElementById("code").innerText = _wpp[this.id].code.toString() + document.getElementById("demoBtn").onclick = _wpp[this.id].action; + + hljs.highlightBlock(document.getElementById("code")); + } + } +} \ No newline at end of file diff --git a/test/oaassist/server/wwwroot/resource/js/wps.js b/test/oaassist/server/wwwroot/resource/js/wps.js new file mode 100644 index 0000000..5a047b2 --- /dev/null +++ b/test/oaassist/server/wwwroot/resource/js/wps.js @@ -0,0 +1,924 @@ +var pluginsMode = location.search.split("=")[1]; //截取url中的参数值 +var pluginType = WpsInvoke.ClientType.wps; //加载项类型wps,et,wpp +var pluginName = "WpsOAAssist"; //加载项名称 +var wpsClient = new WpsClient(pluginType); //初始化一个多进程对象,多进程时才需要 +var clientStr = pluginName + pluginType + "ClientId"; +//单进程封装开始 +/** + * 此方法是根据wps_sdk.js做的调用方法封装 + * 可参照此定义 + * @param {*} funcs 这是在WPS加载项内部定义的方法,采用JSON格式(先方法名,再参数) + * @param {*} front 控制着通过页面执行WPS加载项方法,WPS的界面是否在执行时在前台显示 + * @param {*} jsPluginsXml 指定一个新的WPS加载项配置文件的地址,动态传递jsplugins.xml模式,例如:http://127.0.0.1:3888/jsplugins.xml + * @param {*} isSilent 隐藏打开WPS,如果需要隐藏,那么需要传递front参数为false + */ + +function _WpsInvoke(funcs, front, jsPluginsXml, isSilent) { + var info = {}; + info.funcs = funcs; + if (isSilent) { + //隐藏启动时,front必须为false + front = false; + } + /** + * 下面函数为调起WPS,并且执行加载项WpsOAAssist中的函数dispatcher,该函数的参数为业务系统传递过去的info + */ + if (pluginsMode != 2) { + //单进程 + singleInvoke(info, front, jsPluginsXml, isSilent); + } else { + //多进程 + multInvoke(info, front, jsPluginsXml, isSilent); + } +} + +//单进程 +function singleInvoke(info, front, jsPluginsXml, isSilent) { + WpsInvoke.InvokeAsHttp( + pluginType, // 组件类型 + pluginName, // 插件名,与wps客户端加载的加载的插件名对应 + "dispatcher", // 插件方法入口,与wps客户端加载的加载的插件代码对应,详细见插件代码 + info, // 传递给插件的数据 + function (result) { + // 调用回调,status为0为成功,其他是错误 + if (result.status) { + if (result.status == 100) { + WpsInvoke.AuthHttpesCert( + '请在稍后打开的网页中,点击"高级" => "继续前往",完成授权。' + ); + return; + } + alert(result.message); + } else { + console.log(result.response); + showresult(result.response); + } + }, + front, + jsPluginsXml, + isSilent + ); + + /** + * 接受WPS加载项发送的消息 + * 接收消息:WpsInvoke.RegWebNotify(type,name,callback) + * WPS客户端返回消息: wps.OAAssist.WebNotify(message) + * @param {*} type 加载项对应的插件类型 + * @param {*} name 加载项对应的名字 + * @param {func} callback 接收到WPS客户端的消息后的回调函数,参数为接受到的数据 + */ + WpsInvoke.RegWebNotify(pluginType, pluginName, handleOaMessage); +} +//多进程 +function multInvoke(info, front, jsPluginsXml, isSilent) { + wpsClient.jsPluginsXml = jsPluginsXml + ? jsPluginsXml + : "https://127.0.0.1:3888/jsplugins.xml"; + if (localStorage.getItem(clientStr)) { + wpsClient.clientId = localStorage.getItem(clientStr); + } + if (isSilent) { + wpsClient.StartWpsInSilentMode(pluginName, function () { + //隐藏启动后的回调函数 + mult(info, front); + }); + } else { + mult(info, front); + } + wpsClient.onMessage = handleOaMessage; +} +//多进程二次封装 +function mult(info, front) { + wpsClient.InvokeAsHttp( + pluginName, // 插件名,与wps客户端加载的加载的插件名对应 + "dispatcher", // 插件方法入口,与wps客户端加载的加载的插件代码对应,详细见插件代码 + info, // 传递给插件的数据 + function (result) { + // 调用回调,status为0为成功,其他是错误 + if (wpsClient.clientId) { + localStorage.setItem(clientStr, wpsClient.clientId); + } + if (result.status !== 0) { + console.log(result); + if (result.message == '{"data": "Failed to send message to WPS."}') { + wpsClient.IsClientRunning(function (status) { + console.log(status); + if (status.response == "Client is running.") + alert( + "任务发送失败,WPS 正在执行其他任务,请前往WPS完成当前任务" + ); + else { + wpsClient.clientId = ""; + wpsClient.notifyRegsitered = false; + localStorage.setItem(clientStr, ""); + mult(info); + } + }); + return; + } else if (result.status == 100) { + // WpsInvoke.AuthHttpesCert('请在稍后打开的网页中,点击"高级" => "继续前往",完成授权。') + return; + } + alert(result.message); + } else { + console.log(result.response); + } + }, + front + ); +} +function handleOaMessage(data) { + console.log(data); +} + +function handleOaFunc1(message) { + alert("我是函数handleOaFunc1,我接收到的参数是:" + message); +} +function handleOaFunc2(message) { + alert("我是函数handleOaFunc2,我接收到的参数是:" + message); + var span = window.parent.document.getElementById("webnotifyspan"); + span.innerHTML = message; +} +/** + * 处理WPS加载项的方法返回值 + * + * @param {*} resultData + */ +function showresult(resultData) { + let json = eval("(" + resultData + ")"); + switch (json.message) { + case "GetDocStatus": { + let docstatus = json.docstatus; + if (typeof docstatus != "undefined") { + let str = + "文档保存状态:" + + docstatus.saved + + "\n文档字数:" + + docstatus.words + + "\n文档页数:" + + docstatus.pages; + alert(str); + } + } + } +} +/** + * 这是页面中针对代码显示的变量定义,开发者无需关心 + */ +var _wps = {}; + +// 此处往下,都是对于前端页面如何调用WPS加载项方法的样例,开发者请参考 + +function newDoc() { + console.log("sasaa"); + _WpsInvoke( + [ + { + NewDoc: {}, + }, + ], + true, + "http://127.0.0.1:8080/iestart/jsplugins.xml" + ); // NewDoc方法对应于OA助手dispatcher支持的方法名 +} + +_wps["newDoc"] = { + action: newDoc, + code: _WpsInvoke.toString() + "\n\n" + newDoc.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,打开WPS文字后,新建一个空白doc文档\n\ +\n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行插件中的js函数NewDoc,新建一个空白doc\n\ + funcs参数说明:\n\ + NewDoc方法对应于OA助手dispatcher支持的方法名\n\ +", +}; + +function GetDemoPath(fileName) { + var url = document.location.host; + return document.location.protocol + "//" + url + "/file/" + fileName; +} + +function GetUploadPath() { + var url = document.location.host; + return document.location.protocol + "//" + url + "/Upload"; +} + +function GetDemoPngPath() { + var url = document.location.toString(); + url = decodeURI(url); + if (url.indexOf("/") != -1) { + url = url.substring(0, url.lastIndexOf("/")); + } + if (url.length !== 0) url = url.concat("/WPS.png"); + + if (!String.prototype.startsWith) { + String.prototype.startsWith = function (searchString, position) { + position = position || 0; + return this.indexOf(searchString, position) === position; + }; + } + + if (url.startsWith("file:///")) url = url.substr("file:///".length); + return url; +} + +function openDoc() { + var filePath = prompt( + "请输入打开文件路径(本地或是url):", + GetDemoPath("样章.docx") + ); + var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()); + var uploadFieldName = prompt( + "请输入文档上传到业务系统时自定义字段:", + "自定义字段" + ); + var backupPath = prompt("请输入文档备份路径:"); + + _WpsInvoke([ + { + OpenDoc: { + uploadPath: uploadPath, // 保存文档上传接口 + fileName: filePath, + uploadFieldName: uploadFieldName, + picPath: GetDemoPngPath(), + copyUrl: backupPath, + userName: "东方不败", + }, + }, + ]); // OpenDoc方法对应于OA助手dispatcher支持的方法名 +} + +_wps["openDoc"] = { + action: openDoc, + code: _WpsInvoke.toString() + "\n\n" + openDoc.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ + 打开WPS文字后,将根据文档路径下载并打开对应的文档,保存将自动上传指定服务器地址\n\ +\n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ + uploadPath 保存文档上传接口\n\ + fileName 打开的文档路径\n\ + uploadFieldName 文档上传到业务系统时自定义字段\n\ + picPath 插入图片的路径\n\ + copyUrl 备份的服务器路径\n\ + userName 传给wps要显示的OA用户名\n\ +", +}; + +function onlineEditDoc() { + var filePath = prompt( + "请输入打开文件路径(本地或是url):", + GetDemoPath("样章.docx") + ); + var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()); + var uploadFieldName = prompt( + "请输入文档上传到业务系统时自定义字段:", + "自定义字段" + ); + _WpsInvoke( + [ + { + OnlineEditDoc: { + uploadPath: uploadPath, // 保存文档上传接口 + fileName: filePath, + uploadFieldName: uploadFieldName, + buttonGroups: + "btnSaveAsFile,btnImportDoc,btnPageSetup,btnInsertDate,btnSelectBookmark", //屏蔽功能按钮 + userName: "东方不败", + }, + }, + ], + true + ); // onlineEditDoc方法对应于OA助手dispatcher支持的方法名 +} + +_wps["onlineEditDoc"] = { + action: onlineEditDoc, + code: _WpsInvoke.toString() + "\n\n" + onlineEditDoc.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ + 打开WPS文字后,将根据文档路径在线打开对应的文档,保存将自动上传指定服务器地址\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + onlineEditDoc方法对应于OA助手dispatcher支持的方法名\n\ + uploadPath 保存文档上传接口\n\ + fileName 打开的文档路径\n\ + uploadFieldName 文档上传到业务系统时自定义字段\n\ + buttonGroups 屏蔽的OA助手功能按钮\n\ + userName 传给wps要显示的OA用户名\n\ +", +}; + +function openRevision() { + var filePath = prompt( + "请输入打开文件路径(本地或是url):", + GetDemoPath("样章.docx") + ); + var uploadPath = prompt("请输入文档上传接口:"); + _WpsInvoke([ + { + OpenDoc: { + uploadPath: uploadPath, // 保存文档上传接口 + fileName: filePath, + userName: "王五", //用户名 + revisionCtrl: { + bOpenRevision: true, + bShowRevision: true, + }, + }, + }, + ]); +} + +_wps["openRevision"] = { + action: openRevision, + code: _WpsInvoke.toString() + "\n\n" + openRevision.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,输入参数后,打开WPS文字后,打开指定文档,并打开修订功能,并显示修订\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ + userName 用户名,设置当前编辑用户名\n\ + fileName 打开的文档路径\n\ + revisionCtrl 修订功能控制参数\n\ +", +}; + +function closeRevision() { + var filePath = prompt( + "请输入打开文件路径(本地或是url):", + GetDemoPath("样章.docx") + ); + var uploadPath = prompt("请输入文档上传接口:"); + _WpsInvoke([ + { + OpenDoc: { + uploadPath: uploadPath, // 保存文档上传接口 + fileName: filePath, + userName: "王五", //用户名 + revisionCtrl: { + bOpenRevision: false, + bShowRevision: false, + }, + }, + }, + ]); +} + +_wps["closeRevision"] = { + action: closeRevision, + code: _WpsInvoke.toString() + "\n\n" + closeRevision.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,输入参数后,打开WPS文字后,打开指定文档,并关闭修订功能\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ + userName 用户名,设置当前编辑用户名\n\ + fileName 打开的文档路径\n\ + revisionCtrl 修订功能控制参数\n\ +", +}; + +function protectOpen() { + var filePath = prompt( + "请输入打开文件路径(本地或是url):", + GetDemoPath("样章.docx") + ); + var uploadPath = prompt("请输入文档上传接口:"); + _WpsInvoke([ + { + OpenDoc: { + uploadPath: uploadPath, // 保存文档上传接口 + fileName: filePath, + openType: { + //文档打开方式 + // 文档保护类型,-1:不启用保护模式,0:只允许对现有内容进行修订, + // 1:只允许添加批注,2:只允许修改窗体域(禁止拷贝功能),3:只读 + protectType: 3, + password: "123456", + }, + }, + }, + ]); +} + +_wps["protectOpen"] = { + action: protectOpen, + code: _WpsInvoke.toString() + "\n\n" + protectOpen.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,输入参数后,打开WPS文字后,打开使用保护模式指定文档\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ + uploadPath 保存文档上传接口\n\ + fileName 打开的文档路径\n\ + openType 文档打开方式控制参数 protectType:1:不启用保护模式,0:只允许对现有内容进行修订,\n\ + \t\t1:只允许添加批注,2:只允许修改窗体域(禁止拷贝功能),3:只读 password为密码\n\ +", +}; + +function openWithPassWd() { + var filePath = prompt("请输入打开文件路径(本地或是url):"); + var docPassword = prompt("请输入文档打开密码:"); + var uploadPath = prompt("请输入文档上传接口:"); + _WpsInvoke([ + { + OpenDoc: { + uploadPath: uploadPath, // 保存文档上传接口 + fileName: filePath, + docPassword: { + docPassword: docPassword, // 文档密码 + }, + }, + }, + ]); +} + +_wps["openWithPassWd"] = { + action: openWithPassWd, + code: _WpsInvoke.toString() + "\n\n" + openWithPassWd.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,输入参数后,打开WPS文字后,使用指定密码打开指定加密文档\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ + uploadPath 保存文档上传接口\n\ + fileName 打开的文档路径\n\ + docPassword 文档密码\n\ +", +}; + +function insertRedHeader() { + var filePath = prompt( + "请输入打开文件路径,如果为空则对活动文档套红:", + GetDemoPath("样章.docx") + ); + var templateURL = prompt( + "请输入红头模板路径(本地或是url):", + GetDemoPath("红头文件.docx") + ); + if (filePath != "" && filePath != null) { + _WpsInvoke([ + { + OnlineEditDoc: { + fileName: filePath, + insertFileUrl: templateURL, + bkInsertFile: "Content", //红头模板中填充正文的位置书签名 + buttonGroups: + "btnSaveAsFile,btnImportDoc,btnPageSetup,btnInsertDate,btnSelectBookmark", //屏蔽功能按钮 + }, + }, + ]); + } else { + _WpsInvoke([ + { + InsertRedHead: { + insertFileUrl: templateURL, + bkInsertFile: "Content", //红头模板中填充正文的位置书签名 + }, + }, + ]); + } +} + +_wps["insertRedHeader"] = { + action: insertRedHeader, + code: _WpsInvoke.toString() + "\n\n" + insertRedHeader.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,输入参数后,打开WPS文字后,打开指定文档,然后使用指定红头模板对该文档进行套红头\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ + fileName 打开的文档路径\n\ + insertFileUrl 指定的红头模板\n\ + bkInsertFile 红头模板中正文的位置书签名\n\ + InsertRedHead方法对应于OA助手dispatcher支持的方法名\n\ + insertFileUrl 指定的红头模板\n\ + bkInsertFile 红头模板中正文的位置书签名\n\ +", +}; + +function fillTemplate() { + var filePath = prompt( + "请输入打开文件路径(本地或是url):", + GetDemoPath("样章2.docx") + ); + var templatePath = prompt( + "请输入需要填充的数据的请求地址:", + document.location.protocol + + "//" + + document.location.host + + "/getTemplateData" + ); + + _WpsInvoke([ + { + OpenDoc: { + fileName: filePath, + templateDataUrl: templatePath, + }, + }, + ]); // OpenDoc方法对应于OA助手dispatcher支持的方法名 +} + +_wps["fillTemplate"] = { + action: fillTemplate, + code: _WpsInvoke.toString() + "\n\n" + fillTemplate.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,输入要打开的文档路径,输入文档上传接口,打开WPS文字后,将根据文档路径下载并打开对应的文档,\n\ + 并自动从模板服务器获取模板数据并套用到文档中\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ + fileName 打开的文档路径\n\ + templateDataUrl 模板的服务器路径\n\ +", +}; + +function convertDoc() { + var filePath = prompt( + "请输入打开文件路径(本地或是url):", + GetDemoPath("样章.docx") + ); + var uploadPath = prompt("请输入文档转换后上传接口:", GetUploadPath()); + + _WpsInvoke([ + { + OpenDoc: { + uploadPath: uploadPath, // 保存文档上传接口 + fileName: filePath, + suffix: ".pdf", + uploadWithAppendPath: "1", //与suffix配置使用,传入标志位即可 + }, + }, + ]); // OpenDoc方法对应于OA助手dispatcher支持的方法名 +} + +_wps["convertDoc"] = { + action: convertDoc, + code: _WpsInvoke.toString() + "\n\n" + convertDoc.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,输入要打开的文档路径,输入文档转换后上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ + 打开WPS文字后,将根据文档路径下载并打开对应的文档,转换完将自动上传指定服务器地址\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ + uploadPath 保存文档上传接口\n\ + fileName 打开的文档路径\n\ + suffix 转换类型\n\ + uploadWithAppendPath 保存时一并转换的目标格式\n\ +", +}; + +function taskPaneBookMark() { + var filePath = prompt( + "请输入打开带书签文件路径(本地或是url):", + GetDemoPath("样章.docx") + ); + _WpsInvoke([ + { + taskPaneBookMark: { + fileName: filePath, + userName: "东方不败", + }, + }, + ]); // taskPaneBookMark方法对应于OA助手dispatcher支持的方法名 +} + +_wps["taskPaneBookMark"] = { + action: taskPaneBookMark, + code: _WpsInvoke.toString() + "\n\n" + taskPaneBookMark.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,输入要打开的文档路径,文档中的书签将会在OA助手的Taskpane中显示出来。\n\ + 点击TaskPane中的书签,会自动跳转到书签所对应的文件中的位置,点击Taskpane按F2键可以看Taskpane中的html源码。\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + taskPaneBookMark 方法对应于OA助手dispatcher支持的方法名\n\ + fileName 文档的路径\n\ + userName 传给wps要显示的OA用户名\n\ +", +}; + +function exitWPS() { + _WpsInvoke( + [ + { + ExitWPS: {}, + }, + ], + true + ); +} + +_wps["exitWPS"] = { + action: exitWPS, + code: _WpsInvoke.toString() + "\n\n" + exitWPS.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,关闭已打开的WPS\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议通知WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + ExitWPS 方法对应于OA助手dispatcher支持的方法名\n\ +", +}; + +function getDocStatus() { + _WpsInvoke( + [ + { + GetDocStatus: {}, + }, + ], + false + ); +} + +_wps["getDocStatus"] = { + action: getDocStatus, + code: _WpsInvoke.toString() + "\n\n" + getDocStatus.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,获取活动文档的状态\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议通知WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + GetDocStatus 方法对应于OA助手dispatcher支持的方法名\n\ +", +}; + +//----公文写作的相关方法 这些都必须是在有「公文写作」组件的版本中运行 Start-------- +/** + * 判断当前OS是否是Linux系统 + * + * @returns + */ +function checkOSisLinux() { + if (detectOS() == "Linux") { + return true; + } else { + alert("此方法仅在WPS Linux特定版本支持"); + } +} +/** + * 新建一个使用公文写作打开的公文 + * + */ +function newOfficialDocument() { + if (checkOSisLinux()) { + _WpsInvoke([ + { + NewOfficialDocument: { + isOfficialDocument: true, + }, + }, + ]); // NewOfficialDocument方法对应于OA助手dispatcher支持的方法名 + } +} + +_wps["newOfficialDocument"] = { + action: newOfficialDocument, + code: _WpsInvoke.toString() + "\n\n" + newOfficialDocument.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,打开WPS公文写作后,新建一个公文\n\ +\n\ + 方法使用:\n\ + 页面点击按钮, 通过wps客户端协议来启动WPS, 调用oaassist插件, 执行插件中的js函数NewOfficialDocument, 新建一个默认模板的公文 n\ + funcs参数说明:\n\ + NewOfficialDocument方法对应于OA助手dispatcher支持的方法名 n\ +", +}; + +/** + * 打开一个使用公文写作打开的公文 + */ +function openOfficialDocument() { + if (checkOSisLinux()) { + var filePath = prompt( + "请输入打开文件路径(本地或是url):", + GetDemoPath("公文样章.wps") + ); + var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()); + var uploadFieldName = prompt( + "请输入文档上传到业务系统时自定义字段:", + "自定义字段" + ); + var backupPath = prompt("请输入文档备份路径:"); + _WpsInvoke([ + { + OpenDoc: { + uploadPath: uploadPath, // 保存文档上传接口 + fileName: filePath, + uploadFieldName: uploadFieldName, + picPath: GetDemoPngPath(), + copyUrl: backupPath, + userName: "东方不败", + }, + }, + ]); // OpenDoc方法对应于OA助手dispatcher支持的方法名 + } +} +_wps["openOfficialDocument"] = { + action: openOfficialDocument, + code: _WpsInvoke.toString() + "\n\n" + openOfficialDocument.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ + 打开WPS文字后,将根据文档路径下载并打开对应的文档,保存将自动上传指定服务器地址\n\ +\n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OpenDoc方法对应于OA助手dispatcher支持的方法名\n\ + uploadPath 保存文档上传接口\n\ + fileName 打开的文档路径\n\ + uploadFieldName 文档上传到业务系统时自定义字段\n\ + picPath 插入图片的路径\n\ + copyUrl 备份的服务器路径\n\ + userName 传给wps要显示的OA用户名\n\ +", +}; +/** + * 在线不落地打开一个使用公文写作打开的公文 + */ +function onlineEditOfficialDocument() { + if (checkOSisLinux()) { + var filePath = prompt( + "请输入打开文件路径(本地或是url):", + GetDemoPath("公文样章.wps") + ); + var uploadPath = prompt("请输入文档上传接口:", GetUploadPath()); + var uploadFieldName = prompt( + "请输入文档上传到业务系统时自定义字段:", + "自定义字段" + ); + _WpsInvoke([ + { + OnlineEditDoc: { + uploadPath: uploadPath, // 保存文档上传接口 + fileName: filePath, + uploadFieldName: uploadFieldName, + buttonGroups: + "btnSaveAsFile,btnImportDoc,btnPageSetup,btnInsertDate,btnSelectBookmark", //屏蔽功能按钮 + userName: "东方不败", + }, + }, + ]); // onlineEditDoc方法对应于OA助手dispatcher支持的方法名 + } +} + +_wps["onlineEditOfficialDocument"] = { + action: onlineEditOfficialDocument, + code: _WpsInvoke.toString() + "\n\n" + onlineEditOfficialDocument.toString(), + detail: + "\n\ + 说明:\n\ + 点击按钮,输入要打开的文档路径,输入文档上传接口,如果传的不是有效的服务端地址,将无法使用保存上传功能。\n\ + 打开WPS文字后,将根据文档路径在线打开对应的文档,保存将自动上传指定服务器地址\n\ + \n\ + 方法使用:\n\ + 页面点击按钮,通过wps客户端协议来启动WPS,调用oaassist插件,执行传输数据中的指令\n\ + funcs参数信息说明:\n\ + OnlineEditDoc方法对应于OA助手dispatcher支持的方法名\n\ + uploadPath 保存文档上传接口\n\ + fileName 打开的文档路径\n\ + uploadFieldName 文档上传到业务系统时自定义字段\n\ + buttonGroups 屏蔽的OA助手功能按钮\n\ + userName 传给wps要显示的OA用户名\n\ +", +}; + +/** + * 这是HTML页面上的按钮赋予事件的实现,开发者无需关心,使用自己习惯的方式做开发即可 + */ +window.onload = function () { + var btns = document.getElementsByClassName("btn"); + + for (var i = 0; i < btns.length; i++) { + btns[i].onclick = function (event) { + document.getElementById("blockFunc").style.visibility = "visible"; + var btn2 = document.getElementById("demoBtn"); + btn2.innerText = this.innerText; + document.getElementById("codeDes").innerText = + _wps[this.id].detail.toString(); + document.getElementById("code").innerText = _wps[this.id].code.toString(); + var onBtnAction = _wps[this.id].action; + + // document.getElementById("demoBtn").onclick = onBtnAction //IE不支持箭头函数,改为通用写法 + document.getElementById("demoBtn").onclick = function () { + //IE不支持箭头函数,改为通用写法 + //之下动作是做了对Node服务的判断和oem.ini的设置 + var xhr = new WpsInvoke.CreateXHR(); + xhr.onload = function () { + onBtnAction(); + }; + xhr.onerror = function () { + alert("请确认本地服务端(StartupServer.js)是启动状态"); + return; + }; + xhr.open("get", "http://127.0.0.1:3888/FileList", true); + xhr.send(); + }; + + hljs.highlightBlock(document.getElementById("code")); + }; + } +}; +/** + * 检查操作系统 + * + * @returns Win10 | Win7 | WinVista | Win2003 | WinXP | Win2000 | Linux | Unix | Mac + */ +function detectOS() { + var sUserAgent = navigator.userAgent; + var isWin = navigator.platform == "Win32" || navigator.platform == "Windows"; + var isMac = + navigator.platform == "Mac68K" || + navigator.platform == "MacPPC" || + navigator.platform == "Macintosh" || + navigator.platform == "MacIntel"; + if (isMac) return "Mac"; + var isUnix = navigator.platform == "X11" && !isWin && !isMac; + if (isUnix) return "Unix"; + var isLinux = String(navigator.platform).indexOf("Linux") > -1; + if (isLinux) return "Linux"; + if (isWin) { + var isWin2K = + sUserAgent.indexOf("Windows NT 5.0") > -1 || + sUserAgent.indexOf("Windows 2000") > -1; + if (isWin2K) return "Win2000"; + var isWinXP = + sUserAgent.indexOf("Windows NT 5.1") > -1 || + sUserAgent.indexOf("Windows XP") > -1; + if (isWinXP) return "WinXP"; + var isWin2003 = + sUserAgent.indexOf("Windows NT 5.2") > -1 || + sUserAgent.indexOf("Windows 2003") > -1; + if (isWin2003) return "Win2003"; + var isWinVista = + sUserAgent.indexOf("Windows NT 6.0") > -1 || + sUserAgent.indexOf("Windows Vista") > -1; + if (isWinVista) return "WinVista"; + var isWin7 = + sUserAgent.indexOf("Windows NT 6.1") > -1 || + sUserAgent.indexOf("Windows 7") > -1; + if (isWin7) return "Win7"; + var isWin10 = + sUserAgent.indexOf("Windows NT 6.1") > -1 || + sUserAgent.indexOf("Windows 10") > -1; + if (isWin10) return "Win10"; + } + return "other"; +} diff --git a/test/oaassist/server/wwwroot/resource/js/wps_sdk.js b/test/oaassist/server/wwwroot/resource/js/wps_sdk.js new file mode 100644 index 0000000..ec9ca6e --- /dev/null +++ b/test/oaassist/server/wwwroot/resource/js/wps_sdk.js @@ -0,0 +1,957 @@ +(function (global, factory) { + + "use strict"; + + if (typeof module === "object" && typeof module.exports === "object") { + module.exports = factory(global, true); + } else { + factory(global); + } + +})(typeof window !== "undefined" ? window : this, function (window, noGlobal) { + + "use strict"; + + var bFinished = true; + + function getHttpObj() { + var httpobj = null; + if (IEVersion() < 10) { + try { + httpobj = new XDomainRequest(); + } catch (e1) { + httpobj = new createXHR(); + } + } else { + httpobj = new createXHR(); + } + return httpobj; + } + //兼容IE低版本的创建xmlhttprequest对象的方法 + function createXHR() { + if (typeof XMLHttpRequest != 'undefined') { //兼容高版本浏览器 + return new XMLHttpRequest(); + } else if (typeof ActiveXObject != 'undefined') { //IE6 采用 ActiveXObject, 兼容IE6 + var versions = [ //由于MSXML库有3个版本,因此都要考虑 + 'MSXML2.XMLHttp.6.0', + 'MSXML2.XMLHttp.3.0', + 'MSXML2.XMLHttp' + ]; + + for (var i = 0; i < versions.length; i++) { + try { + return new ActiveXObject(versions[i]); + } catch (e) { + //跳过 + } + } + } else { + throw new Error('您的浏览器不支持XHR对象'); + } + } + + function startWps(options) { + if (!bFinished && !options.concurrent) { + if (options.callback) + options.callback({ + status: 1, + message: "上一次请求没有完成" + }); + return; + } + bFinished = false; + + function startWpsInnder(tryCount) { + if (tryCount <= 0) { + if (bFinished) + return; + bFinished = true; + if (options.callback) + options.callback({ + status: 2, + message: "请允许浏览器打开WPS Office" + }); + return; + } + var xmlReq = getHttpObj(); + //WPS客户端提供的接收参数的本地服务,HTTP服务端口为58890,HTTPS服务端口为58891 + //这俩配置,取一即可,不可同时启用 + xmlReq.open('POST', options.url); + xmlReq.onload = function (res) { + bFinished = true; + if (options.callback) { + options.callback({ + status: 0, + response: IEVersion() < 10 ? xmlReq.responseText : res.target.response + }); + } + } + xmlReq.ontimeout = xmlReq.onerror = function (res) { + xmlReq.bTimeout = true; + if (tryCount == options.tryCount && options.bPop) { //打开wps并传参 + window.location.href = "ksoWPSCloudSvr://start=RelayHttpServer" //是否启动wps弹框 + } + setTimeout(function () { + startWpsInnder(tryCount - 1) + }, 1000); + } + if (IEVersion() < 10) { + xmlReq.onreadystatechange = function () { + if (xmlReq.readyState != 4) + return; + if (xmlReq.bTimeout) { + return; + } + if (xmlReq.status === 200) + xmlReq.onload(); + else + xmlReq.onerror(); + } + } + xmlReq.timeout = options.timeout; + xmlReq.send(options.sendData) + } + startWpsInnder(options.tryCount); + return; + } + + var fromCharCode = String.fromCharCode; + // encoder stuff + var cb_utob = function (c) { + if (c.length < 2) { + var cc = c.charCodeAt(0); + return cc < 0x80 ? c : + cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6)) + + fromCharCode(0x80 | (cc & 0x3f))) : + (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f)) + + fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + + fromCharCode(0x80 | (cc & 0x3f))); + } else { + var cc = 0x10000 + + (c.charCodeAt(0) - 0xD800) * 0x400 + + (c.charCodeAt(1) - 0xDC00); + return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07)) + + fromCharCode(0x80 | ((cc >>> 12) & 0x3f)) + + fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + + fromCharCode(0x80 | (cc & 0x3f))); + } + }; + var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; + var utob = function (u) { + return u.replace(re_utob, cb_utob); + }; + var _encode = function (u) { + var isUint8Array = Object.prototype.toString.call(u) === '[object Uint8Array]'; + if (isUint8Array) + return u.toString('base64') + else + return btoa(utob(String(u))); + } + + if (typeof window.btoa !== 'function') window.btoa = func_btoa; + + function func_btoa(input) { + var str = String(input); + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + for ( + // initialize result and counter + var block, charCode, idx = 0, map = chars, output = ''; + // if the next str index does not exist: + // change the mapping table to "=" + // check if d has no fractional digits + str.charAt(idx | 0) || (map = '=', idx % 1); + // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 + output += map.charAt(63 & block >> 8 - idx % 1 * 8) + ) { + charCode = str.charCodeAt(idx += 3 / 4); + if (charCode > 0xFF) { + throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); + } + block = block << 8 | charCode; + } + return output; + } + + var encode = function (u, urisafe) { + return !urisafe ? + _encode(u) : + _encode(String(u)).replace(/[+\/]/g, function (m0) { + return m0 == '+' ? '-' : '_'; + }).replace(/=/g, ''); + }; + + function IEVersion() { + var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 + var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器 + var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器 + var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1; + if (isIE) { + var reIE = new RegExp("MSIE (\\d+\\.\\d+);"); + reIE.test(userAgent); + var fIEVersion = parseFloat(RegExp["$1"]); + if (fIEVersion == 7) { + return 7; + } else if (fIEVersion == 8) { + return 8; + } else if (fIEVersion == 9) { + return 9; + } else if (fIEVersion == 10) { + return 10; + } else { + return 6; //IE版本<=7 + } + } else if (isEdge) { + return 20; //edge + } else if (isIE11) { + return 11; //IE11 + } else { + return 30; //不是ie浏览器 + } + } + + function WpsStart(options) { + var startInfo = { + "name": options.name, + "function": options.func, + "info": options.param.param, + "jsPluginsXml": options.param.jsPluginsXml + }; + var strData = JSON.stringify(startInfo); + if (IEVersion() < 10) { + try { + eval("strData = '" + JSON.stringify(startInfo) + "';"); + } catch (err) { + + } + } + + var baseData = encode(strData); + var url = options.urlBase + "/" + options.clientType + "/runParams"; + var data = "ksowebstartup" + options.clientType + "://" + baseData; + startWps({ + url: url, + sendData: data, + callback: options.callback, + tryCount: options.tryCount, + bPop: options.bPop, + timeout: 5000, + concurrent: false, + client: options.wpsclient + }); + } + + function WpsStartWrap(options) { + WpsStart({ + clientType: options.clientType, + name: options.name, + func: options.func, + param: options.param, + urlBase: options.urlBase, + callback: options.callback, + tryCount: 4, + bPop: true, + wpsclient: options.wpsclient, + }) + } + + /** + * 支持浏览器触发,WPS有返回值的启动 + * + * @param {*} clientType 组件类型 + * @param {*} name WPS加载项名称 + * @param {*} func WPS加载项入口方法 + * @param {*} param 参数:包括WPS加载项内部定义的方法,参数等 + * @param {*} callback 回调函数 + * @param {*} tryCount 重试次数 + * @param {*} bPop 是否弹出浏览器提示对话框 + */ + var exId = 0; + function WpsStartWrapExInner(options) { + var infocontent = options.param.param; + if (!options.wpsclient) { + infocontent = JSON.stringify(options.param.param); + var rspUrl = options.urlBase + "/transferEcho/runParams"; + var time = new Date(); + var cmdId = "js" + time.getTime() + "_" + exId; + var funcEx = "var res = " + options.func; + var cbCode = "var xhr = new XMLHttpRequest();xhr.open('POST', '" + rspUrl + "');xhr.send(JSON.stringify({id: '" + cmdId + "', response: res}));" //res 为func执行返回值 + var infoEx = infocontent + ");" + cbCode + "void(0"; + options.func = funcEx; + infocontent = infoEx; + } + var startInfo = { + "name": options.name, + "function": options.func, + "info": infocontent, + "showToFront": options.param.showToFront, + "jsPluginsXml": options.param.jsPluginsXml, + }; + + var strData = JSON.stringify(startInfo); + if (IEVersion() < 10) { + try { + eval("strData = '" + JSON.stringify(startInfo) + "';"); + } catch (err) { + + } + } + + var baseData = encode(strData); + var wrapper; + + if (!options.wpsclient) { + var url = options.urlBase + "/transfer/runParams"; + var data = "ksowebstartup" + options.clientType + "://" + baseData; + wrapper = { + id: cmdId, + app: options.clientType, + data: data + }; + } + else { + var url = options.urlBase + "/transferEx/runParams"; + wrapper = { + id: options.wpsclient.clientId, + app: options.clientType, + data: baseData, + mode: options.wpsclient.silentMode ? "true" : "false" + }; + } + wrapper = JSON.stringify(wrapper); + startWps({ + url: url, + sendData: wrapper, + callback: options.callback, + tryCount: options.tryCount, + bPop: options.bPop, + timeout: 0, + concurrent: options.concurrent, + client: options.wpsclient + }); + } + + var serverVersion = "wait" + var cloudSvrStart = true; + function WpsStartWrapVersionInner(options) { + if (serverVersion == "wait") { + if (cloudSvrStart == false) { + window.location.href = "ksoWPSCloudSvr://start=RelayHttpServer" //是否启动wps弹框 + } + startWps({ + url: options.urlBase + '/version', + data: "", + callback: function (res) { + if (res.status !== 0) { + options.callback(res) + return; + } + serverVersion = res.response; + cloudSvrStart = true; + options.tryCount = 1 + options.bPop = false + if (serverVersion === "") { + WpsStart(options) + } else if (serverVersion < "1.0.1" && options.wpsclient) { + if (options.callback) { + options.callback({ + status: 4, + message: "当前客户端不支持,请升级客户端" + }) + } + } else { + WpsStartWrapExInner(options); + } + }, + tryCount: 4, + bPop: true, + timeout: 5000, + concurrent: options.concurrent + }); + } else { + if (serverVersion === "") { + WpsStartWrap(options) + } else if (serverVersion < "1.0.1" && options.wpsclient) { + if (options.callback) { + options.callback({ + status: 4, + message: "当前客户端不支持,请升级客户端" + }) + } + } else { + WpsStartWrapExInner(options); + } + } + } + + var RegWebNotifyMap = { wps: {}, wpp: {}, et: {} } + var bWebNotifyUseTimeout = true + function WebNotifyUseTimeout(value) { + bWebNotifyUseTimeout = value ? true : false + } + /** + * 注册一个前端页面接收WPS传来消息的方法 + * @param {*} clientType wps | et | wpp + * @param {*} name WPS加载项的名称 + * @param {*} callback 回调函数 + */ + function RegWebNotify(clientType, name, callback, wpsclient) { + if (clientType != "wps" && clientType != "wpp" && clientType != "et") + return; + var paramStr = {} + if (wpsclient) { + if (wpsclient.notifyRegsitered == true) { + return + } + wpsclient.notifyRegsitered = true; + paramStr = { + clientId: wpsclient.clientId, + name: name, + type: clientType + } + } + else { + if (typeof callback != 'function') + return + if (RegWebNotifyMap[clientType][name]) { + RegWebNotifyMap[clientType][name] = callback; + return + } + var RegWebNotifyID = new Date().valueOf() + '' + paramStr = { + id: RegWebNotifyID, + name: name, + type: clientType + } + RegWebNotifyMap[clientType][name] = callback + } + + var askItem = function () { + var xhr = getHttpObj() + xhr.onload = function (e) { + if (xhr.responseText == "WPSInnerMessage_quit") { + return; + } + if (wpsclient) { + wpsclient.OnRegWebNotify(xhr.responseText) + } else { + var func = RegWebNotifyMap[clientType][name] + func(xhr.responseText) + } + window.setTimeout(askItem, 300) + } + xhr.onerror = function (e) { + if (bWebNotifyUseTimeout) + window.setTimeout(askItem, 1000) + else + window.setTimeout(askItem, 10000) + } + xhr.ontimeout = function (e) { + if (bWebNotifyUseTimeout) + window.setTimeout(askItem, 300) + else + window.setTimeout(askItem, 10000) + } + if (IEVersion() < 10) { + xhr.onreadystatechange = function () { + if (xhr.readyState != 4) + return; + if (xhr.bTimeout) { + return; + } + if (xhr.status === 200) + xhr.onload(); + else + xhr.onerror(); + } + } + xhr.open('POST', GetUrlBase() + '/askwebnotify', true) + if (bWebNotifyUseTimeout) + xhr.timeout = 2000; + xhr.send(JSON.stringify(paramStr)) + } + + window.setTimeout(askItem, 2000) + } + + function GetUrlBase() { + if (location.protocol == "http:") + return "http://127.0.0.1:58890" + return "https://127.0.0.1:58891" + } + + function WpsStartWrapVersion(clientType, name, func, param, callback, showToFront, jsPluginsXml) { + var paramEx = { + jsPluginsXml: jsPluginsXml ? jsPluginsXml : "", + showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, + param: (typeof (param) == 'object' ? param : JSON.parse(param)) + } + var options = { + clientType: clientType, + name: name, + func: func, + param: paramEx, + urlBase: GetUrlBase(), + callback: callback, + wpsclient: undefined, + concurrent: true + } + WpsStartWrapVersionInner(options); + } + + //从外部浏览器远程调用 WPS 加载项中的方法 + var WpsInvoke = { + InvokeAsHttp: WpsStartWrapVersion, + InvokeAsHttps: WpsStartWrapVersion, + RegWebNotify: RegWebNotify, + ClientType: { + wps: "wps", + et: "et", + wpp: "wpp" + }, + CreateXHR: getHttpObj, + IsClientRunning: IsClientRunning + } + + window.wpsclients = []; + /** + * @constructor WpsClient wps客户端 + * @param {string} clientType 必传参数,加载项类型,有效值为"wps","wpp","et";分别表示文字,演示,电子表格 + */ + function WpsClient(clientType) { + /** + * 设置RegWebNotify的回调函数,加载项给业务端发消息通过该函数 + * @memberof WpsClient + * @member onMessage + */ + this.onMessage; + + /** + * 设置加载项路径 + * @memberof WpsClient + * @member jsPluginsXml + */ + this.jsPluginsXml; + + /** + * 内部成员,外部无需调用 + */ + this.notifyRegsitered = false; + this.clientId = ""; + this.concurrent = false; + this.clientType = clientType; + this.firstRequest = true; + + /** + * 内部函数,外部无需调用 + * @param {*} options + */ + this.initWpsClient = function (options) { + options.clientType = this.clientType + options.wpsclient = this + options.concurrent = this.firstRequest ? true : this.concurrent + this.firstRequest = false; + WpsStartWrapVersionInner(options) + } + + /** + * 以http启动 + * @param {string} name 加载项名称 + * @param {string} func 要调用的加载项中的函数行 + * @param {string} param 在加载项中执行函数func要传递的数据 + * @param {function({int, string})} callback 回调函数,status = 0 表示成功,失败请查看message信息 + * @param {bool} showToFront 设置wps是否显示到前面来 + * @return {string} "Failed to send message to WPS." 发送消息失败,客户端已关闭; + * "WPS Addon is not response." 加载项阻塞,函数执行失败 + */ + this.InvokeAsHttp = function (name, func, param, callback, showToFront) { + function clientCallback(res) { + //this不是WpsClient + if (res.status !== 0 || serverVersion < "1.0.1") { + if (callback) callback(res); + return; + } + var resObject = JSON.parse(res.response); + if (this.client.clientId == "") { + this.client.clientId = resObject.clientId; + } + this.client.concurrent = true; + if (typeof resObject.data == "object") + res.response = JSON.stringify(resObject.data); + else + res.response = resObject.data; + if (IEVersion() < 10) + eval(" res.response = '" + res.response + "';"); + if (callback) + callback(res); + this.client.RegWebNotify(name); + } + var paramEx = { + jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "", + showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, + param: (typeof (param) == 'object' ? param : JSON.parse(param)) + } + this.initWpsClient({ + name: name, + func: func, + param: paramEx, + urlBase: GetUrlBase(), + callback: clientCallback + }) + } + + /** + * 以https启动 + * @param {string} name 加载项名称 + * @param {string} func 要调用的加载项中的函数行 + * @param {string} param 在加载项中执行函数func要传递的数据 + * @param {function({int, string})} callback 回调函数,status = 0 表示成功,失败请查看message信息 + * @param {bool} showToFront 设置wps是否显示到前面来 + */ + this.InvokeAsHttps = function (name, func, param, callback, showToFront) { + var paramEx = { + jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "", + showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, + param: (typeof (param) == 'object' ? param : JSON.parse(param)) + } + this.initWpsClient({ + name: name, + func: func, + param: paramEx, + urlBase: GetUrlBase(), + callback: callback + }) + } + + /** + * 内部函数,外部无需调用 + * @param {*} name + */ + this.RegWebNotify = function (name) { + RegWebNotify(this.clientType, name, null, this); + } + + this.OnRegWebNotify = function (message) { + if (this.onMessage) + this.onMessage(message) + } + + /** + * 以静默模式启动客户端 + * @param {string} name 必传参数,加载项名称 + * @param {function({int, string})} [callback] 回调函数,status = 0 表示成功,失败请查看message信息 + */ + this.StartWpsInSilentMode = function (name, callback) { + function initCallback(res) { + //this不是WpsClient + if (res.status !== 0 || serverVersion < "1.0.1") { + if (callback) callback(res); + return; + } + if (this.client.clientId == "") { + this.client.clientId = JSON.parse(res.response).clientId; + window.wpsclients[window.wpsclients.length] = { name: name, client: this.client }; + } + res.response = JSON.stringify(JSON.parse(res.response).data); + this.client.concurrent = true; + if (callback) { + callback(res); + } + this.client.RegWebNotify(name); + } + var paramEx = { + jsPluginsXml: this.jsPluginsXml, + showToFront: false, + param: { status: "InitInSilentMode" } + } + this.silentMode = true; + this.initWpsClient({ + name: name, + func: "", + param: paramEx, + urlBase: GetUrlBase(), + callback: initCallback + }) + } + + /** + * 显示客户端到最前面 + * @param {string} name 必传参数,加载项名称 + * @param {function({int, string})} [callback] 回调函数 + */ + this.ShowToFront = function (name, callback) { + if (serverVersion < "1.0.1") { + if (callback) { + callback({ + status: 4, + message: "当前客户端不支持,请升级客户端" + }); + return; + } + return; + } + if (this.clientId == "") { + if (callback) callback({ + status: 3, + message: "没有静默启动客户端" + }); + return; + } + var paramEx = { + jsPluginsXml: "", + showToFront: true, + param: { status: "ShowToFront" } + } + this.initWpsClient({ + name: name, + func: "", + param: paramEx, + urlBase: GetUrlBase(), + callback: callback + }) + } + + /** + * 关闭未显示出来的静默启动客户端 + * @param {string} name 必传参数,加载项名称 + * @param {function({int, string})} [callback] 回调函数 + */ + this.CloseSilentClient = function (name, callback) { + if (serverVersion < "1.0.1") { + if (callback) { + callback({ + status: 4, + message: "当前客户端不支持,请升级客户端" + }); + return; + } + return; + } + if (this.clientId == "") { + if (callback) callback({ + status: 3, + message: "没有静默启动客户端" + }); + return; + } + var paramEx = { + jsPluginsXml: "", + showToFront: false, + param: undefined + } + var func; + if (this.clientType == "wps") + func = "wps.WpsApplication().Quit" + else if (this.clientType == "et") + func = "wps.EtApplication().Quit" + else if (this.clientType == "wpp") + func = "wps.WppApplication().Quit" + + function closeSilentClient(res) { + if (res.status == 0) + this.client.clientId = "" + if (callback) callback(res); + return; + } + this.initWpsClient({ + name: name, + func: func, + param: paramEx, + urlBase: GetUrlBase(), + callback: closeSilentClient + }) + } + + /** + * 当前客户端是否在运行,使用WpsClient.IsClientRunning()进行调用 + * @param {function({int, string})} [callback] 回调函数,"Client is running." 客户端正在运行 + * "Client is not running." 客户端没有运行 + */ + this.IsClientRunning = function (callback) { + if (serverVersion < "1.0.1") { + if (callback) { + callback({ + status: 4, + message: "当前客户端不支持,请升级客户端" + }); + return; + } + return; + } + IsClientRunning(this.clientType, callback, this) + } + } + + function InitSdk() { + var url = GetUrlBase() + "/version"; + startWps({ + url: url, + data: "", + callback: function (res) { + if (res.status !== 0) { + cloudSvrStart = false; + return; + } + if (serverVersion == "wait") { + serverVersion = res.response; + cloudSvrStart = true; + } + }, + tryCount: 1, + bPop: false, + timeout: 5000 + }); + } + + if (typeof noGlobal === "undefined") { + window.WpsInvoke = WpsInvoke; + window.WpsClient = WpsClient; + window.WebNotifyUseTimeout = WebNotifyUseTimeout; + InitSdk(); + } + + /** + * 当前客户端是否在运行,使用WpsInvoke.IsClientRunning()进行调用 + * @param {string} clientType 加载项类型 + * @param {function} [callback] 回调函数,"Client is running." 客户端正在运行 + * "Client is not running." 客户端没有运行 + */ + function IsClientRunning(clientType, callback, wpsclient) { + var url = GetUrlBase() + "/isRunning"; + var wrapper = { + id: wpsclient == undefined ? undefined : wpsclient.clientId, + app: clientType + } + wrapper = JSON.stringify(wrapper); + startWps({ + url: url, + sendData: wrapper, + callback: callback, + tryCount: 1, + bPop: false, + timeout: 2000, + concurrent: true, + client: wpsclient + }); + } + + function WpsAddonGetAllConfig(callBack) { + var baseData; + startWps({ + url: GetUrlBase() + "/publishlist", + type: "GET", + sendData: baseData, + callback: callBack, + tryCount: 3, + bPop: true, + timeout: 5000, + concurrent: true + }); + } + + function WpsAddonVerifyStatus(element, callBack) { + var xmlReq = getHttpObj(); + var offline = element.online === "false"; + var url = offline ? element.url : element.url + "ribbon.xml"; + xmlReq.open("POST", GetUrlBase() + "/redirect/runParams"); + xmlReq.onload = function (res) { + if (offline && !res.target.response.startsWith("7z")) { + callBack({ status: 1, msg: "不是有效的7z格式" + url }); + } else if (!offline && !res.target.response.startsWith(">> 6)) + + fromCharCode(0x80 | (cc & 0x3f))) : + (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f)) + + fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + + fromCharCode(0x80 | (cc & 0x3f))); + } else { + var cc = 0x10000 + + (c.charCodeAt(0) - 0xD800) * 0x400 + + (c.charCodeAt(1) - 0xDC00); + return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07)) + + fromCharCode(0x80 | ((cc >>> 12) & 0x3f)) + + fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + + fromCharCode(0x80 | (cc & 0x3f))); + } + }; + var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; + var utob = function (u) { + return u.replace(re_utob, cb_utob); + }; + var _encode = function (u) { + var isUint8Array = Object.prototype.toString.call(u) === '[object Uint8Array]'; + if (isUint8Array) + return u.toString('base64') + else + return btoa(utob(String(u))); + } + + if (typeof window.btoa !== 'function') window.btoa = func_btoa; + + function func_btoa(input) { + var str = String(input); + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + for ( + // initialize result and counter + var block, charCode, idx = 0, map = chars, output = ''; + // if the next str index does not exist: + // change the mapping table to "=" + // check if d has no fractional digits + str.charAt(idx | 0) || (map = '=', idx % 1); + // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 + output += map.charAt(63 & block >> 8 - idx % 1 * 8) + ) { + charCode = str.charCodeAt(idx += 3 / 4); + if (charCode > 0xFF) { + throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); + } + block = block << 8 | charCode; + } + return output; + } + + /** + * 将字符串进行Base64编码 + * @param {*} u 需要编码的数据 + * @param {*} urisafe 返回值,编码后的数据 + * @returns urisafe + */ + var encode = function (u, urisafe) { + return !urisafe ? + _encode(u) : + _encode(String(u)).replace(/[+\/]/g, function (m0) { + return m0 == '+' ? '-' : '_'; + }).replace(/=/g, ''); + }; + + /** + * 获取IE浏览器版本 + * @returns IE浏览器版本 + */ + function IEVersion() { + var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 + var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器 + var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器 + var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1; + if (isIE) { + var reIE = new RegExp("MSIE (\\d+\\.\\d+);"); + reIE.test(userAgent); + var fIEVersion = parseFloat(RegExp["$1"]); + if (fIEVersion == 7) { + return 7; + } else if (fIEVersion == 8) { + return 8; + } else if (fIEVersion == 9) { + return 9; + } else if (fIEVersion == 10) { + return 10; + } else { + return 6; //IE版本<=7 + } + } else if (isEdge) { + return 20; //edge + } else if (isIE11) { + return 11; //IE11 + } else { + return 30; //不是ie浏览器 + } + } + + /** + * 启动wps客户端,加载项执行操作,无返回值 + * @param {*} options 参数对象,详情见下: + * @param {*} clientType 加载项类型, wps / wpp / et + * @param {*} name 加载项名称 + * @param {*} func 客户端加载项要执行的方法 + * @param {*} param 客户端家乡执行方法的参数 + * @param {*} urlBase 网页路径前缀 + * @param {*} callback 回调函数 + * @param {*} tryCount 请求失败后的尝试次数 + * @param {*} bPop 是否弹出浏览器提示对话框 + * @param {*} wpsclient wpsclient对象 + */ + function WpsStart(options) { + var startInfo = { + "name": options.name, + "function": options.func, + "info": options.param.param, + "jsPluginsXml": options.param.jsPluginsXml + }; + var strData = JSON.stringify(startInfo); + if (IEVersion() < 10) { + try { + eval("strData = '" + JSON.stringify(startInfo) + "';"); + } catch (err) { + + } + } + + var baseData = encode(strData); + var url = options.urlBase + "/" + options.clientType + "/runParams"; + var data = "ksowebstartup" + options.clientType + "://" + baseData; + startWps({ + url: url, + sendData: data, + callback: options.callback, + tryCount: options.tryCount, + bPop: options.bPop, + timeout: 5000, + concurrent: false, + client: options.wpsclient + }); + } + + /** + * 服务端版本为空时,通过该接口启动wps + * @param {*} options 参数对象,详情见下: + * @param {*} clientType 加载项类型, wps / wpp / et + * @param {*} name 加载项名称 + * @param {*} func 客户端加载项要执行的方法 + * @param {*} param 客户端家乡执行方法的参数 + * @param {*} urlBase 网页路径前缀 + * @param {*} callback 回调函数 + * @param {*} wpsclient wpsclient对象 + * @param {*} concurrent 请求是否同步发送 + */ + function WpsStartWrap(options) { + WpsStart({ + clientType: options.clientType, + name: options.name, + func: options.func, + param: options.param, + urlBase: options.urlBase, + callback: options.callback, + tryCount: 4, + bPop: true, + wpsclient: options.wpsclient, + }) + } + + /** + * 支持浏览器触发,WPS有返回值的启动 + * + * @param {*} clientType 组件类型 + * @param {*} name WPS加载项名称 + * @param {*} func WPS加载项入口方法 + * @param {*} param 参数:包括WPS加载项内部定义的方法,参数等 + * @param {*} callback 回调函数 + * @param {*} tryCount 重试次数 + * @param {*} bPop 是否弹出浏览器提示对话框 + */ + var exId = 0; + function WpsStartWrapExInner(options) { + var infocontent = options.param.param; + if (!options.wpsclient || options.wpsclient.single) { + infocontent = JSON.stringify(options.param.param); + var rspUrl = options.urlBase + "/transferEcho/runParams"; + var time = new Date(); + var cmdId = "js" + time.getTime() + "_" + exId; + var funcEx = "var res = " + options.func; + var cbCode = "var xhr = new XMLHttpRequest();xhr.open('POST', '" + rspUrl + "');xhr.send(JSON.stringify({id: '" + cmdId + "', response: res}));" //res 为func执行返回值 + var infoEx = infocontent + ");" + cbCode + "void(0"; + options.func = funcEx; + infocontent = infoEx; + } + var startInfo = { + "name": options.name, + "function": options.func, + "info": infocontent, + "showToFront": options.param.showToFront, + "jsPluginsXml": options.param.jsPluginsXml, + }; + + var strData = JSON.stringify(startInfo); + if (IEVersion() < 10) { + try { + eval("strData = '" + JSON.stringify(startInfo) + "';"); + } catch (err) { + + } + } + + var baseData = encode(strData); + var wrapper; + + if (!options.wpsclient|| options.wpsclient.single) { + var url = options.urlBase + "/transfer/runParams"; + var data = "ksowebstartup" + options.clientType + "://" + baseData; + wrapper = { + id: cmdId, + app: options.clientType, + data: data, + serverId: serverId, + mode: options.silentMode ? "true" : "false", + }; + } + else { + var url = options.urlBase + "/transferEx/runParams"; + wrapper = { + id: options.wpsclient.clientId, + app: options.clientType, + data: baseData, + mode: options.wpsclient.silentMode ? "true" : "false", + serverId: serverId + }; + } + wrapper = JSON.stringify(wrapper); + startWps({ + url: url, + sendData: wrapper, + callback: options.callback, + tryCount: options.tryCount, + bPop: options.bPop, + timeout: 0, + concurrent: options.concurrent, + client: options.wpsclient + }); + } + + var serverVersion = "wait" + var cloudSvrStart = true; + var initCloudsvr = false; + /** + * 获取服务端版本号的接口 + * @param {*} options 参数对象,详情见下: + * @param {*} clientType 加载项类型, wps / wpp / et + * @param {*} name 加载项名称 + * @param {*} func 客户端加载项要执行的方法 + * @param {*} param 客户端家乡执行方法的参数 + * @param {*} urlBase 网页路径前缀 + * @param {*} callback 回调函数 + * @param {*} wpsclient wpsclient对象 + * @param {*} concurrent 请求是否同步发送 + */ + function WpsStartWrapVersionInner(options) { + if (serverVersion == "wait") { + if (cloudSvrStart == false) { + InitWpsCloudSvr(); + initCloudsvr = true; + } + startWps({ + url: options.urlBase + '/version', + sendData: JSON.stringify({ serverId: serverId }), + callback: function (res) { + if (res.status !== 0) { + options.callback(res) + return; + } + serverVersion = res.response; + cloudSvrStart = true; + options.tryCount = 1 + options.bPop = false + if (serverVersion === "") { + WpsStart(options) + } else if (serverVersion < "1.0.1" && options.wpsclient) { + options.wpsclient.single = true; + WpsStartWrapExInner(options); + } else { + WpsStartWrapExInner(options); + } + }, + tryCount: 4, + bPop: true, + timeout: 5000, + concurrent: options.concurrent + }); + } else { + options.tryCount = 4 + options.bPop = true + if (serverVersion === "") { + WpsStartWrap(options) + } else if (serverVersion < "1.0.1" && options.wpsclient) { + options.wpsclient.single = true; + WpsStartWrapExInner(options); + } else { + WpsStartWrapExInner(options); + } + } + } + + var HeartBeatCode = + "function getHttpObj() {\n" + + " var httpobj = null;\n" + + " if (IEVersion() < 10) {\n" + + " try {\n" + + " httpobj = new XDomainRequest();\n" + + " } catch (e1) {\n" + + " httpobj = new createXHR();\n" + + " }\n" + + " } else {\n" + + " httpobj = new createXHR();\n" + + " }\n" + + " return httpobj;\n" + + " }\n" + + " \n" + + " function createXHR() {\n" + + " if (typeof XMLHttpRequest != 'undefined') {\n" + + " return new XMLHttpRequest();\n" + + " } else if (typeof ActiveXObject != 'undefined') {\n" + + " var versions = [\n" + + " 'MSXML2.XMLHttp.6.0',\n" + + " 'MSXML2.XMLHttp.3.0',\n" + + " 'MSXML2.XMLHttp'\n" + + " ];\n" + + " \n" + + " for (var i = 0; i < versions.length; i++) {\n" + + " try {\n" + + " return new ActiveXObject(versions[i]);\n" + + " } catch (e) {\n" + + " \n" + + " }\n" + + " }\n" + + " } else {\n" + + " throw new Error('您的浏览器不支持XHR对象');\n" + + " }\n" + + " }\n" + + " \n" + + " function IEVersion() {\n" + + " var userAgent = navigator.userAgent; \n" + + " var isIE = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1;\n" + + " var isEdge = userAgent.indexOf('Edge') > -1 && !isIE; \n" + + " var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1;\n" + + " if (isIE) {\n" + + " var reIE = new RegExp('MSIE (\\d+\\.\\d+);');\n" + + " reIE.test(userAgent);\n" + + " var fIEVersion = parseFloat(RegExp['$1']);\n" + + " if (fIEVersion == 7) {\n" + + " return 7;\n" + + " } else if (fIEVersion == 8) {\n" + + " return 8;\n" + + " } else if (fIEVersion == 9) {\n" + + " return 9;\n" + + " } else if (fIEVersion == 10) {\n" + + " return 10;\n" + + " } else {\n" + + " return 6; \n" + + " }\n" + + " } else if (isEdge) {\n" + + " return 20; \n" + + " } else if (isIE11) {\n" + + " return 11; \n" + + " } else {\n" + + " return 30; \n" + + " }\n" + + " }\n" + + " var heartBeatStart = false;\n" + + " function checkLastRegTime() {\n" + + " var now = new Date().valueOf();\n" + + " var TimeGap = now - LastRegTime;\n" + + " if (TimeGap > 5000 && !heartBeatStart) {\n" + + " HeartBeat();\n" + + " heartBeatStart = true;\n" + + " }\n" + + " }\n" + + " \n" + + " function HeartBeat() {\n" + + " var heartBeatItem = function () {\n" + + " var xhr = getHttpObj();\n" + + " xhr.onload = function (e) {\n" + + " self.setTimeout(heartBeatItem, 5000);\n" + + " }\n" + + " xhr.onerror = function (e) {\n" + + " self.setTimeout(heartBeatItem, 5000);\n" + + " }\n" + + " xhr.ontimeout = function (e) {\n" + + " self.setTimeout(heartBeatItem, 5000);\n" + + " }\n" + + " xhr.open('POST', 'http://127.0.0.1:58890/askwebnotify', true);\n" + + " xhr.timeout = 2000;\n" + + " xhr.send(JSON.stringify(paramStr));\n" + + " }\n" + + " heartBeatItem();\n" + + " }\n" + + " \n" + + " var paramStr;\n" + + " var startCheck = false;\n" + + " self.addEventListener('message', function (event) {\n" + + " var data = event.data;\n" + + " paramStr = data.param\n" + + " paramStr.heartBeat = true\n" + + " LastRegTime = data.LastRegTime;\n" + + " if (!startCheck) {\n" + + " startCheck = true;\n" + + " self.setInterval(checkLastRegTime, 5000)\n" + + " }\n" + + " }, false);\n" + /** + * 生成guid的接口 + * @returns guid + */ + function guid() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + } + + /** + * 开启多用户的接口 + */ + var serverId = undefined + function EnableMultiUser() { + serverId = getServerId(); + } + + /** + * 自定义协议启动服务端 + * 默认不带参数serverId,linux未升级之前不要使用多用户 + */ + function InitWpsCloudSvr () { + if(serverId == undefined) + window.location.href = "ksoWPSCloudSvr://start=RelayHttpServer"//是否启动wps弹框 + else + window.location.href = "ksoWPSCloudSvr://start=RelayHttpServer" + "&serverId=" + serverId //是否启动wps弹框 + } + + /** + * 获取serverId的接口 + * @returns serverId + */ + function getServerId() { + if (window.localStorage) { + if (localStorage.getItem("serverId")) { + // + } + else { + localStorage.setItem("serverId", guid()); + } + return localStorage.getItem("serverId"); + } + else { + return guid(); + } + } + + /** + * 将字符串转成二进制,这里用来将字符串化后的js代码转成二进制文件 + * @param {*} code + * @returns js文件对象的url + */ + function codeToBlob(code) { + var blob = new Blob([code], { type: 'text/javascript' }); // 生成js文件对象 + var objectURL = window.URL.createObjectURL(blob); // 生成js文件的url + return objectURL; + } + + var RegWebNotifyMap = { wps: {}, wpp: {}, et: {} } + var bWebNotifyUseTimeout = true + function WebNotifyUseTimeout(value) { + bWebNotifyUseTimeout = value ? true : false + } + var g_businessId = Number(Math.random().toString().substr(3, 5) + Date.parse(new Date())).toString(36); + var HeartBeatWorker + if (window.Worker) { + try { + HeartBeatWorker = new Worker(codeToBlob(HeartBeatCode)); + } catch (error) { + // + } + } + var g_LastRegTime; + /** + * 注册一个前端页面接收WPS传来消息的方法 + * @param {*} clientType wps | et | wpp + * @param {*} name WPS加载项的名称 + * @param {*} callback 回调函数 + * @param {*} wpsclient wpsclient对象 + */ + function RegWebNotify(clientType, name, callback, wpsclient) { + if (clientType != "wps" && clientType != "wpp" && clientType != "et") + return; + var paramStr = {} + if (wpsclient) { + if (wpsclient.notifyRegsitered == true) { + return + } + wpsclient.notifyRegsitered = true; + paramStr = { + clientId: wpsclient.clientId, + name: name, + type: clientType, + serverId: serverId + } + if (HeartBeatWorker) + paramStr.businessId = g_businessId + } + else { + if (typeof callback != 'function') + return + if (RegWebNotifyMap[clientType][name]) { + RegWebNotifyMap[clientType][name] = callback; + return + } + var RegWebNotifyID = new Date().valueOf() + '' + paramStr = { + id: RegWebNotifyID, + name: name, + type: clientType, + serverId: serverId + } + if (HeartBeatWorker) + paramStr.businessId = g_businessId + RegWebNotifyMap[clientType][name] = callback + } + + var askItem = function () { + var xhr = getHttpObj() + xhr.onload = function (e) { + if (xhr.responseText == "WPSInnerMessage_quit") { + return; + } + try { + var resText = JSON.parse(xhr.responseText); + if (typeof resText == 'object') { + paramStr.messageId = resText.msgId; + } + if (wpsclient) { + if (typeof resText.data == 'object') // 如果发的数据是字符串化后的json对象,这里的resText.data就是一个json对象,可以输出自己想要的json数据 + wpsclient.OnRegWebNotify(resText.data.data) + else + wpsclient.OnRegWebNotify(resText.data) + } else { + var func = RegWebNotifyMap[clientType][name] + if (typeof resText.data == 'object') // 如果发的数据是字符串化后的json对象,这里的resText.data就是一个json对象,可以输出自己想要的json数据 + func(resText.data.data) + else + func(resText.data) + } + } + catch (e) { + // 这里做一个容错,即使json解析失败,也要把msgId提取出来,发回给服务端,避免消息清不掉一直重复发送 + // 同时把data也取出来,但是格式无法保证 + var str = xhr.responseText + var idx1 = str.indexOf(":") + var idx2 = str.indexOf(",") + paramStr.messageId = parseInt(str.substring(idx1 + 1, idx2)) + var idx3 = str.indexOf("\"data\"") + var idx4 = str.indexOf("}") + var data = str.substring(idx3, idx4) + if (wpsclient) { + if (data) + wpsclient.OnRegWebNotify(data) + else + wpsclient.OnRegWebNotify(xhr.responseText) + } else { + var func = RegWebNotifyMap[clientType][name] + if (data) + func(data) + else + func(xhr.responseText) + } + } + window.setTimeout(askItem, 300) + } + xhr.onerror = function (e) { + if (bWebNotifyUseTimeout) + window.setTimeout(askItem, 1000) + else + window.setTimeout(askItem, 10000) + } + xhr.ontimeout = function (e) { + if (bWebNotifyUseTimeout) + window.setTimeout(askItem, 300) + else + window.setTimeout(askItem, 10000) + } + if (IEVersion() < 10) { + xhr.onreadystatechange = function () { + if (xhr.readyState != 4) + return; + if (xhr.bTimeout) { + return; + } + if (xhr.status === 200) + xhr.onload(); + else + xhr.onerror(); + } + } + xhr.open('POST', GetUrlBase() + '/askwebnotify', true) + if (bWebNotifyUseTimeout) + xhr.timeout = 2000; + if (HeartBeatWorker) { + g_LastRegTime = new Date().valueOf(); + var param = { + param: { + name: name, + type: clientType, + businessId: g_businessId, + serverId: serverId + }, + LastRegTime: g_LastRegTime + } + HeartBeatWorker.postMessage(param) + } + xhr.send(JSON.stringify(paramStr)); + } + window.setTimeout(askItem, 2000) + } + + /** + * 获取网页路径前缀 + * @returns url前缀 + */ + function GetUrlBase() { + if (location.protocol == "https:") + return "https://127.0.0.1:58891" + return "http://127.0.0.1:58890" + } + + /** + * 获取服务端版本号的接口,这里主要是初始化一些参数 + * @param {*} clientType 加载项类型, wps / wpp / et + * @param {*} name 加载项名称 + * @param {*} func 客户端加载项要执行的方法 + * @param {*} param 客户端家乡执行方法的参数 + * @param {*} callback 回调函数 + * @param {*} showToFront 设置客户端是否显示到前面 + * @param {*} jsPluginsXml 设置加载项路径 + * @param {*} silentMode 静默启动WPS + */ + function WpsStartWrapVersion(clientType, name, func, param, callback, showToFront, jsPluginsXml,silentMode) { + var paramEx = { + jsPluginsXml: jsPluginsXml ? jsPluginsXml : "", + showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, + param: (typeof (param) == 'object' ? param : JSON.parse(param)) + } + var options = { + clientType: clientType, + name: name, + func: func, + param: paramEx, + urlBase: GetUrlBase(), + callback: callback, + wpsclient: undefined, + concurrent: true, + silentMode:silentMode + } + WpsStartWrapVersionInner(options); + } + + //从外部浏览器远程调用 WPS 加载项中的方法 + var WpsInvoke = { + InvokeAsHttp: WpsStartWrapVersion, + InvokeAsHttps: WpsStartWrapVersion, + RegWebNotify: RegWebNotify, + ClientType: { + wps: "wps", + et: "et", + wpp: "wpp" + }, + CreateXHR: getHttpObj, + IsClientRunning: IsClientRunning + } + + window.wpsclients = []; + /** + * @constructor WpsClient wps客户端 + * @param {string} clientType 必传参数,加载项类型,有效值为"wps","wpp","et";分别表示文字,演示,电子表格 + */ + function WpsClient(clientType) { + /** + * 设置RegWebNotify的回调函数,加载项给业务端发消息通过该函数 + * @memberof WpsClient + * @member onMessage + */ + this.onMessage; + + /** + * 设置加载项路径 + * @memberof WpsClient + * @member jsPluginsXml + */ + this.jsPluginsXml; + + /** + * 内部成员,外部无需调用 + */ + this.notifyRegsitered = false; + this.clientId = ""; + this.concurrent = false; + this.clientType = clientType; + this.firstRequest = true; + + /** + * 内部函数,外部无需调用 + * @param {*} options + */ + this.initWpsClient = function (options) { + options.clientType = this.clientType + options.wpsclient = this + options.concurrent = this.firstRequest ? true : this.concurrent + this.firstRequest = false; + WpsStartWrapVersionInner(options) + } + + /** + * 以http启动 + * @param {string} name 加载项名称 + * @param {string} func 要调用的加载项中的函数行 + * @param {string} param 在加载项中执行函数func要传递的数据 + * @param {function({int, string})} callback 回调函数,status = 0 表示成功,失败请查看message信息 + * @param {bool} showToFront 设置wps是否显示到前面来 + * @return {string} "Failed to send message to WPS." 发送消息失败,客户端已关闭; + * "WPS Addon is not response." 加载项阻塞,函数执行失败 + */ + this.InvokeAsHttp = function (name, func, param, callback, showToFront) { + function clientCallback(res) { + //this不是WpsClient + if (res.status !== 0 || serverVersion < "1.0.1") { + if (callback) + callback(res); + RegWebNotify(clientType, name, this.client.onMessage) + return; + } + var resObject = JSON.parse(res.response); + if (this.client.clientId == "") { + this.client.clientId = resObject.clientId; + } + this.client.concurrent = true; + if (typeof resObject.data == "object") + res.response = JSON.stringify(resObject.data); + else + res.response = resObject.data; + if (IEVersion() < 10) + eval(" res.response = '" + res.response + "';"); + if (callback) + callback(res); + this.client.RegWebNotify(name); + } + var paramEx = { + jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "", + showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, + param: (typeof (param) == 'object' ? param : JSON.parse(param)) + } + this.initWpsClient({ + name: name, + func: func, + param: paramEx, + urlBase: GetUrlBase(), + callback: clientCallback + }) + } + + /** + * 以https启动 + * @param {string} name 加载项名称 + * @param {string} func 要调用的加载项中的函数行 + * @param {string} param 在加载项中执行函数func要传递的数据 + * @param {function({int, string})} callback 回调函数,status = 0 表示成功,失败请查看message信息 + * @param {bool} showToFront 设置wps是否显示到前面来 + */ + this.InvokeAsHttps = function (name, func, param, callback, showToFront) { + var paramEx = { + jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "", + showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, + param: (typeof (param) == 'object' ? param : JSON.parse(param)) + } + this.initWpsClient({ + name: name, + func: func, + param: paramEx, + urlBase: GetUrlBase(), + callback: callback + }) + } + + /** + * 内部函数,外部无需调用 + * @param {*} name + */ + this.RegWebNotify = function (name) { + RegWebNotify(this.clientType, name, null, this); + } + + /** + * 消息注册函数的回调函数 + * @param {*} message 客户端发来的消息 + */ + this.OnRegWebNotify = function (message) { + if (this.onMessage) + this.onMessage(message) + } + + /** + * 以静默模式启动客户端 + * @param {string} name 必传参数,加载项名称 + * @param {function({int, string})} [callback] 回调函数,status = 0 表示成功,失败请查看message信息 + */ + this.StartWpsInSilentMode = function (name, callback) { + function initCallback(res) { + //this不是WpsClient + if (res.status !== 0 || serverVersion < "1.0.1") { + if (callback) + callback(res); + RegWebNotify(clientType, name, this.client.onMessage) + return; + } + if (this.client.clientId == "") { + this.client.clientId = JSON.parse(res.response).clientId; + window.wpsclients[window.wpsclients.length] = { name: name, client: this.client }; + } + res.response = JSON.stringify(JSON.parse(res.response).data); + this.client.concurrent = true; + if (callback) { + callback(res); + } + this.client.RegWebNotify(name); + } + var paramEx = { + jsPluginsXml: this.jsPluginsXml, + showToFront: false, + param: { status: "InitInSilentMode" } + } + this.silentMode = true; + this.initWpsClient({ + name: name, + func: "", + param: paramEx, + urlBase: GetUrlBase(), + callback: initCallback + }) + } + + /** + * 显示客户端到最前面 + * @param {string} name 必传参数,加载项名称 + * @param {function({int, string})} [callback] 回调函数 + */ + this.ShowToFront = function (name, callback) { + if (serverVersion < "1.0.1") { + if (callback) { + callback({ + status: 4, + message: "当前客户端不支持,请升级客户端" + }); + return; + } + return; + } + if (this.clientId == "") { + if (callback) callback({ + status: 3, + message: "没有静默启动客户端" + }); + return; + } + var paramEx = { + jsPluginsXml: "", + showToFront: true, + param: { status: "ShowToFront" } + } + this.initWpsClient({ + name: name, + func: "", + param: paramEx, + urlBase: GetUrlBase(), + callback: callback + }) + } + + /** + * 关闭未显示出来的静默启动客户端 + * @param {string} name 必传参数,加载项名称 + * @param {function({int, string})} [callback] 回调函数 + */ + this.CloseSilentClient = function (name, callback) { + if (serverVersion < "1.0.1") { + if (callback) { + callback({ + status: 4, + message: "当前客户端不支持,请升级客户端" + }); + return; + } + return; + } + if (this.clientId == "") { + if (callback) callback({ + status: 3, + message: "没有静默启动客户端" + }); + return; + } + var paramEx = { + jsPluginsXml: "", + showToFront: false, + param: undefined + } + var func; + if (this.clientType == "wps") + func = "wps.WpsApplication().Quit" + else if (this.clientType == "et") + func = "wps.EtApplication().Quit" + else if (this.clientType == "wpp") + func = "wps.WppApplication().Quit" + + function closeSilentClient(res) { + if (res.status == 0) + this.client.clientId = "" + if (callback) callback(res); + return; + } + this.initWpsClient({ + name: name, + func: func, + param: paramEx, + urlBase: GetUrlBase(), + callback: closeSilentClient + }) + } + + /** + * 当前客户端是否在运行,使用WpsClient.IsClientRunning()进行调用 + * @param {function({int, string})} [callback] 回调函数,"Client is running." 客户端正在运行 + * "Client is not running." 客户端没有运行 + */ + this.IsClientRunning = function (callback) { + if (serverVersion < "1.0.1") { + if (callback) { + callback({ + status: 4, + message: "当前客户端不支持,请升级客户端" + }); + return; + } + return; + } + IsClientRunning(this.clientType, callback, this) + } + } + + /** + * 初始化sdk,用来减少在服务进程启动时自定义协议弹框出现的次数 + */ + function InitSdk() { + var url = GetUrlBase() + "/version"; + startWps({ + url: url, + callback: function (res) { + if (res.status !== 0) { + cloudSvrStart = false; + return; + } + if (serverVersion == "wait") { + InitMultiUser(); + } + }, + tryCount: 1, + bPop: false, + timeout: 1000 + }); + } + InitSdk(); + + /** + * 初始化多用户模式 + */ + function InitMultiUser() { + var url = GetUrlBase() + "/version"; + startWps({ + url: url, + sendData: JSON.stringify({ serverId: serverId }), + callback: function (res) { + if (res.status !== 0) { + cloudSvrStart = false; + return; + } + if (serverVersion == "wait") { + serverVersion = res.response; + cloudSvrStart = true; + } + }, + tryCount: 1, + bPop: false, + timeout: 1000 + }); + } + + if (typeof noGlobal === "undefined") { + window.WpsInvoke = WpsInvoke; + window.WpsClient = WpsClient; + window.WebNotifyUseTimeout = WebNotifyUseTimeout; + window.EnableMultiUser = EnableMultiUser; + } + + /** + * 当前客户端是否在运行,使用WpsInvoke.IsClientRunning()进行调用 + * @param {string} clientType 加载项类型 + * @param {function} [callback] 回调函数,"Client is running." 客户端正在运行 + * "Client is not running." 客户端没有运行 + */ + function IsClientRunning(clientType, callback, wpsclient) { + var url = GetUrlBase() + "/isRunning"; + var wrapper = { + id: wpsclient == undefined ? undefined : wpsclient.clientId, + app: clientType, + serverId: serverId + } + wrapper = JSON.stringify(wrapper); + startWps({ + url: url, + sendData: wrapper, + callback: callback, + tryCount: 1, + bPop: false, + timeout: 2000, + concurrent: true, + client: wpsclient + }); + } + + /** + * 获取publish.xml的内容 + * @param {*} callBack 回调函数 + */ + function WpsAddonGetAllConfig(callBack) { + var baseData = JSON.stringify({ serverId: serverId }); + startWps({ + url: GetUrlBase() + "/publishlist", + type: "POST", + sendData: baseData, + callback: callBack, + tryCount: 3, + bPop: true, + timeout: 5000, + concurrent: true + }); + } + + /** + * 检查ribbon.xml文件是否有效 + * @param {*} element 参数对象 + * @param {*} callBack 回调函数 + */ + function WpsAddonVerifyStatus(element, callBack) { + var xmlReq = getHttpObj(); + var offline = element.online === "false"; + var url = offline ? element.url : element.url + "ribbon.xml"; + xmlReq.open("POST", GetUrlBase() + "/redirect/runParams"); + xmlReq.onload = function (res) { + if (offline && !res.target.response.startsWith("7z")) { + callBack({ status: 1, msg: "不是有效的7z格式" + url }); + } else if (!offline && !res.target.response.startsWith(" + + + + + + + + title + + + + + + + + + + +
+
+
+ + + +
+
+
+ + + + \ No newline at end of file diff --git a/test/oaassist/server/wwwroot/resource/wps.html b/test/oaassist/server/wwwroot/resource/wps.html new file mode 100644 index 0000000..3e68c5e --- /dev/null +++ b/test/oaassist/server/wwwroot/resource/wps.html @@ -0,0 +1,67 @@ + + + + + + + + + title + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+
+
+ + + + \ No newline at end of file