This commit is contained in:
Carsten "Tomcat" Book 2014-09-22 13:09:04 +02:00
Родитель 90b843db8e 79a0a7362d
Коммит 76da7d9d6f
230 изменённых файлов: 4465 добавлений и 2935 удалений

Просмотреть файл

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
The backout of bug 994190 needed a clobber.
Bug 1063304 moved IPDL PMobileConnection into its own namespace and needed a clobber.

Просмотреть файл

@ -246,6 +246,15 @@ pref("security.alternate_certificate_error_page", "certerror");
pref("security.warn_viewing_mixed", false); // Warning is disabled. See Bug 616712.
// 2 = strict certificate pinning checks.
// This default preference is more strict than Firefox because B2G
// currently does not have a way to install local root certificates.
// Strict checking is effectively equivalent to non-strict checking as
// long as that is true. If an ability to add local certificates is
// added, there may be a need to change this pref.
pref("security.cert_pinning.enforcement_level", 2);
// Override some named colors to avoid inverse OS themes
pref("ui.-moz-dialog", "#efebe7");
pref("ui.-moz-dialogtext", "#101010");

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7ef0bf06ce1c98cbe68aa52e2ecd862acb23e9c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3802009e1ab6c3ddfc3eb15522e3140a96b33336"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c7ef0bf06ce1c98cbe68aa52e2ecd862acb23e9c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3802009e1ab6c3ddfc3eb15522e3140a96b33336"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7ef0bf06ce1c98cbe68aa52e2ecd862acb23e9c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3802009e1ab6c3ddfc3eb15522e3140a96b33336"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f3e998242fb9a857cf50f5bf3a02304a530ea617"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7ef0bf06ce1c98cbe68aa52e2ecd862acb23e9c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3802009e1ab6c3ddfc3eb15522e3140a96b33336"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c7ef0bf06ce1c98cbe68aa52e2ecd862acb23e9c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3802009e1ab6c3ddfc3eb15522e3140a96b33336"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7ef0bf06ce1c98cbe68aa52e2ecd862acb23e9c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3802009e1ab6c3ddfc3eb15522e3140a96b33336"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -135,10 +135,10 @@
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="960533f716ce31dfad357e87fa2f1d9ee5e94674"/>
<project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="893238eb1215f8fd4f3747169170cc5e1cc33969"/>
<project name="kernel_lk" path="bootable/bootloader/lk" remote="b2g" revision="fda40423ffa573dc6cafd3780515010cb2a086be"/>
<project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="b2af89ae378a119819a9c86d9a12e573c7130459"/>
<project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="30b96dfca99cb384bf520a16b81f3aba56f09907"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="5b71e40213f650459e95d35b6f14af7e88d8ab62"/>
<project name="platform_external_libnfc-nci" path="external/libnfc-nci" remote="t2m" revision="4186bdecb4dae911b39a8202252cc2310d91b0be"/>
<project name="platform/frameworks/av" path="frameworks/av" revision="c1814713bd2d07c2af0c236007badc8732a34324"/>
<project name="platform/frameworks/av" path="frameworks/av" revision="ea2f399b3ca0a23524d2828f85f69902caefc22e"/>
<project name="platform/frameworks/base" path="frameworks/base" revision="6b58ab45e3e56c1fc20708cc39fa2264c52558df"/>
<project name="platform/frameworks/native" path="frameworks/native" revision="a46a9f1ac0ed5662d614c277cbb14eb3f332f365"/>
<project name="platform/hardware/libhardware" path="hardware/libhardware" revision="7196881a0e9dd7bfbbcf0af64c8064e70f0fa094"/>
@ -154,5 +154,5 @@
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="54a712b46fe937dacdaed9b1261c63847129a719"/>
<project name="platform/system/qcom" path="system/qcom" revision="63e3f6f176caad587d42bba4c16b66d953fb23c2"/>
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="d8952a42771045fca73ec600e2b42a4c7129d723"/>
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="5d1dbc698de7294697373b436dd44e240f40e1ac"/>
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="7704e16da545f4207812e593743d6743e1afb9c5"/>
</manifest>

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7ef0bf06ce1c98cbe68aa52e2ecd862acb23e9c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3802009e1ab6c3ddfc3eb15522e3140a96b33336"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f3e998242fb9a857cf50f5bf3a02304a530ea617"/>

Просмотреть файл

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "b5f6c10e258311d9f04ed759291bbe6af10a772b",
"revision": "a491e07757d721d4bea7302cfbb2b18460a3820d",
"repo_path": "/integration/gaia-central"
}

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c7ef0bf06ce1c98cbe68aa52e2ecd862acb23e9c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3802009e1ab6c3ddfc3eb15522e3140a96b33336"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c7ef0bf06ce1c98cbe68aa52e2ecd862acb23e9c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3802009e1ab6c3ddfc3eb15522e3140a96b33336"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7ef0bf06ce1c98cbe68aa52e2ecd862acb23e9c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3802009e1ab6c3ddfc3eb15522e3140a96b33336"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f3e998242fb9a857cf50f5bf3a02304a530ea617"/>

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c7ef0bf06ce1c98cbe68aa52e2ecd862acb23e9c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3802009e1ab6c3ddfc3eb15522e3140a96b33336"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -438,6 +438,8 @@
#if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
@BINPATH@/components/MmsService.js
@BINPATH@/components/MmsService.manifest
@BINPATH@/components/MobileConnectionService.js
@BINPATH@/components/MobileConnectionService.manifest
@BINPATH@/components/MobileMessageDatabaseService.js
@BINPATH@/components/MobileMessageDatabaseService.manifest
@BINPATH@/components/RadioInterfaceLayer.js
@ -445,8 +447,6 @@
@BINPATH@/components/RILContentHelper.js
@BINPATH@/components/TelephonyService.js
@BINPATH@/components/TelephonyService.manifest
@BINPATH@/components/MobileConnectionGonkService.js
@BINPATH@/components/MobileConnectionGonkService.manifest
#endif // MOZ_WIDGET_GONK && MOZ_B2G_RIL
#ifndef MOZ_WIDGET_GONK

Просмотреть файл

@ -101,6 +101,7 @@ skip-if = os == "linux" # Bug 924307
[browser_aboutHome.js]
skip-if = e10s # Bug ?????? - no about:home support yet
[browser_aboutSyncProgress.js]
[browser_action_keyword.js]
[browser_addKeywordSearch.js]
skip-if = e10s
[browser_alltabslistener.js]

Просмотреть файл

@ -0,0 +1,92 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
let gOnSearchComplete = null;
function* promise_first_result(inputText) {
gURLBar.focus();
gURLBar.value = inputText.slice(0, -1);
EventUtils.synthesizeKey(inputText.slice(-1) , {});
yield promiseSearchComplete();
// On Linux, the popup may or may not be open at this stage. So we need
// additional checks to ensure we wait long enough.
yield promisePopupShown(gURLBar.popup);
let firstResult = gURLBar.popup.richlistbox.firstChild;
return firstResult;
}
add_task(function*() {
// This test is only relevant if UnifiedComplete is enabled.
if (!Services.prefs.getBoolPref("browser.urlbar.unifiedcomplete"))
return;
let tab = gBrowser.selectedTab = gBrowser.addTab("about:mozilla");
let tabs = [tab];
registerCleanupFunction(() => {
for (let tab of tabs)
gBrowser.removeTab(tab);
PlacesUtils.bookmarks.removeItem(itemId);
});
yield promiseTabLoadEvent(tab);
let itemId =
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
NetUtil.newURI("http://example.com/?q=%s"),
PlacesUtils.bookmarks.DEFAULT_INDEX,
"test");
PlacesUtils.bookmarks.setKeywordForBookmark(itemId, "keyword");
let result = yield promise_first_result("keyword something");
isnot(result, null, "Expect a keyword result");
is(result.getAttribute("type"), "action keyword", "Expect correct `type` attribute");
is(result.getAttribute("actiontype"), "keyword", "Expect correct `actiontype` attribute");
is(result.getAttribute("title"), "test", "Expect correct title");
// We need to make a real URI out of this to ensure it's normalised for
// comparison.
let uri = NetUtil.newURI(result.getAttribute("url"));
is(uri.spec, makeActionURI("keyword", {url: "http://example.com/?q=something", input: "keyword something"}).spec, "Expect correct url");
is_element_visible(result._title, "Title element should be visible");
is(result._title.childNodes.length, 1, "Title element should have 1 child");
is(result._title.childNodes[0].nodeName, "#text", "That child should be a text node");
is(result._title.childNodes[0].data, "test", "Node should contain the name of the bookmark");
is_element_visible(result._extra, "Extra element should be visible");
is(result._extra.childNodes.length, 1, "Title element should have 1 child");
is(result._extra.childNodes[0].nodeName, "span", "That child should be a span node");
let span = result._extra.childNodes[0];
is(span.childNodes.length, 1, "span element should have 1 child");
is(span.childNodes[0].nodeName, "#text", "That child should be a text node");
is(span.childNodes[0].data, "something", "Node should contain the query for the keyword");
is_element_hidden(result._url, "URL element should be hidden");
// Click on the result
info("Normal click on result");
let tabPromise = promiseTabLoadEvent(tab);
EventUtils.synthesizeMouseAtCenter(result, {});
let loadEvent = yield tabPromise;
is(loadEvent.target.location.href, "http://example.com/?q=something", "Tab should have loaded from clicking on result");
// Middle-click on the result
info("Middle-click on result");
result = yield promise_first_result("keyword somethingmore");
isnot(result, null, "Expect a keyword result");
// We need to make a real URI out of this to ensure it's normalised for
// comparison.
uri = NetUtil.newURI(result.getAttribute("url"));
is(uri.spec, makeActionURI("keyword", {url: "http://example.com/?q=somethingmore", input: "keyword somethingmore"}).spec, "Expect correct url");
tabPromise = promiseWaitForEvent(gBrowser.tabContainer, "TabOpen");
EventUtils.synthesizeMouseAtCenter(result, {button: 1});
let tabOpenEvent = yield tabPromise;
let newTab = tabOpenEvent.target;
tabs.push(newTab);
loadEvent = yield promiseTabLoadEvent(newTab);
is(loadEvent.target.location.href, "http://example.com/?q=somethingmore", "Tab should have loaded from middle-clicking on result");
});

Просмотреть файл

@ -1,53 +1,11 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function promisePopupShown(popup) {
if (popup.state = "open")
return Promise.resolve();
let deferred = Promise.defer();
popup.addEventListener("popupshown", function onPopupShown(event) {
popup.removeEventListener("popupshown", onPopupShown);
deferred.resolve();
});
return deferred.promise;
}
function promisePopupHidden(popup) {
if (popup.state = "closed")
return Promise.resolve();
let deferred = Promise.defer();
popup.addEventListener("popuphidden", function onPopupHidden(event) {
popup.removeEventListener("popuphidden", onPopupHidden);
deferred.resolve();
});
popup.closePopup();
return deferred.promise;
}
function* check_a11y_label(inputText, expectedLabel) {
let searchDeferred = Promise.defer();
let onSearchComplete = gURLBar.onSearchComplete;
registerCleanupFunction(() => {
gURLBar.onSearchComplete = onSearchComplete;
});
gURLBar.onSearchComplete = function () {
ok(gURLBar.popupOpen, "The autocomplete popup is correctly open");
onSearchComplete.apply(gURLBar);
gURLBar.onSearchComplete = onSearchComplete;
searchDeferred.resolve();
}
gURLBar.focus();
gURLBar.value = inputText.slice(0, -1);
EventUtils.synthesizeKey(inputText.slice(-1) , {});
yield searchDeferred.promise;
yield promiseSearchComplete();
// On Linux, the popup may or may not be open at this stage. So we need
// additional checks to ensure we wait long enough.
yield promisePopupShown(gURLBar.popup);

Просмотреть файл

@ -670,3 +670,90 @@ function makeActionURI(action, params) {
let url = "moz-action:" + action + "," + JSON.stringify(params);
return NetUtil.newURI(url);
}
function is_hidden(element) {
var style = element.ownerDocument.defaultView.getComputedStyle(element, "");
if (style.display == "none")
return true;
if (style.visibility != "visible")
return true;
if (style.display == "-moz-popup")
return ["hiding","closed"].indexOf(element.state) != -1;
// Hiding a parent element will hide all its children
if (element.parentNode != element.ownerDocument)
return is_hidden(element.parentNode);
return false;
}
function is_visible(element) {
var style = element.ownerDocument.defaultView.getComputedStyle(element, "");
if (style.display == "none")
return false;
if (style.visibility != "visible")
return false;
if (style.display == "-moz-popup" && element.state != "open")
return false;
// Hiding a parent element will hide all its children
if (element.parentNode != element.ownerDocument)
return is_visible(element.parentNode);
return true;
}
function is_element_visible(element, msg) {
isnot(element, null, "Element should not be null, when checking visibility");
ok(is_visible(element), msg);
}
function is_element_hidden(element, msg) {
isnot(element, null, "Element should not be null, when checking visibility");
ok(is_hidden(element), msg);
}
function promisePopupEvent(popup, eventSuffix) {
let endState = {shown: "open", hidden: "closed"}[eventSuffix];
if (popup.state = endState)
return Promise.resolve();
let eventType = "popup" + eventSuffix;
let deferred = Promise.defer();
popup.addEventListener(eventType, function onPopupShown(event) {
popup.removeEventListener(eventType, onPopupShown);
deferred.resolve();
});
return deferred.promise;
}
function promisePopupShown(popup) {
return promisePopupEvent(popup, "shown");
}
function promisePopupHidden(popup) {
return promisePopupEvent(popup, "hidden");
}
let gURLBarOnSearchComplete = null;
function promiseSearchComplete() {
info("Waiting for onSearchComplete");
let deferred = Promise.defer();
if (!gURLBarOnSearchComplete) {
gURLBarOnSearchComplete = gURLBar.onSearchComplete;
registerCleanupFunction(() => {
gURLBar.onSearchComplete = gURLBarOnSearchComplete;
});
}
gURLBar.onSearchComplete = function () {
ok(gURLBar.popupOpen, "The autocomplete popup is correctly open");
gURLBarOnSearchComplete.apply(gURLBar);
deferred.resolve();
}
return deferred.promise;
}

Просмотреть файл

@ -155,6 +155,10 @@
returnValue = action.params.url;
break;
}
case "keyword": {
returnValue = action.params.input;
break;
}
}
}
@ -313,8 +317,10 @@
if (switchToTabHavingURI(url) &&
isTabEmpty(prevTab))
gBrowser.removeTab(prevTab);
return;
} else if (action.type == "keyword") {
url = action.params.url;
}
return;
}
continueOperation.call(this);
}
@ -1005,10 +1011,18 @@
// Check if this is meant to be an action
let action = this.mInput._parseActionUrl(url);
if (action) {
if (action.type == "switchtab")
url = action.param;
else
return;
// TODO (bug 1054816): Centralise the implementation of actions
// into a JS module.
switch (action.type) {
case "switchtab": //Fall through.
case "keyword": {
url = action.params.url;
break;
}
default: {
return;
}
}
}
// respect the usual clicking subtleties

Просмотреть файл

@ -182,6 +182,21 @@ function injectLoopAPI(targetWindow) {
}
},
/**
* Releases the callData for a specific loopCallId
*
* The result of this call will be a free call session slot.
*
* @param {int} loopCallId
*/
releaseCallData: {
enumerable: true,
writable: true,
value: function(loopCallId) {
MozLoopService.releaseCallData(loopCallId);
}
},
/**
* Returns the contacts API.
*

Просмотреть файл

@ -81,6 +81,159 @@ let gFxAOAuthTokenData = null;
let gFxAOAuthProfile = null;
let gErrors = new Map();
/**
* Attempts to open a websocket.
*
* A new websocket interface is used each time. If an onStop callback
* was received, calling asyncOpen() on the same interface will
* trigger a "alreay open socket" exception even though the channel
* is logically closed.
*/
function CallProgressSocket(progressUrl, callId, token) {
if (!progressUrl || !callId || !token) {
throw new Error("missing required arguments");
}
this._progressUrl = progressUrl;
this._callId = callId;
this._token = token;
}
CallProgressSocket.prototype = {
/**
* Open websocket and run hello exchange.
* Sends a hello message to the server.
*
* @param {function} Callback used after a successful handshake
* over the progressUrl.
* @param {function} Callback used if an error is encountered
*/
connect: function(onSuccess, onError) {
this._onSuccess = onSuccess;
this._onError = onError ||
(reason => {console.warn("MozLoopService::callProgessSocket - ", reason);});
if (!onSuccess) {
this._onError("missing onSuccess argument");
return;
}
let uri = Services.io.newURI(this._progressUrl, null, null);
// Allow _websocket to be set for testing.
if (!this._websocket && !Services.io.offline) {
this._websocket = Cc["@mozilla.org/network/protocol;1?name=" + uri.scheme]
.createInstance(Ci.nsIWebSocketChannel);
} else {
this._onError("IO offline");
return;
}
this._websocket.asyncOpen(uri, this._progressUrl, this, null);
},
/**
* Listener method, handles the start of the websocket stream.
* Sends a hello message to the server.
*
* @param {nsISupports} aContext Not used
*/
onStart: function() {
let helloMsg = {
messageType: "hello",
callId: this._callId,
auth: this._token,
};
try { // in case websocket has closed before this handler is run
this._websocket.sendMsg(JSON.stringify(helloMsg));
}
catch (error) {
this._onError(error);
}
},
/**
* Listener method, called when the websocket is closed.
*
* @param {nsISupports} aContext Not used
* @param {nsresult} aStatusCode Reason for stopping (NS_OK = successful)
*/
onStop: function(aContext, aStatusCode) {
if (!this._handshakeComplete) {
this._onError("[" + aStatusCode + "]");
}
},
/**
* Listener method, called when the websocket is closed by the server.
* If there are errors, onStop may be called without ever calling this
* method.
*
* @param {nsISupports} aContext Not used
* @param {integer} aCode the websocket closing handshake close code
* @param {String} aReason the websocket closing handshake close reason
*/
onServerClose: function(aContext, aCode, aReason) {
if (!this._handshakeComplete) {
this._onError("[" + aCode + "]" + aReason);
}
},
/**
* Listener method, called when the websocket receives a message.
*
* @param {nsISupports} aContext Not used
* @param {String} aMsg The message data
*/
onMessageAvailable: function(aContext, aMsg) {
let msg = {};
try {
msg = JSON.parse(aMsg);
}
catch (error) {
console.error("MozLoopService: error parsing progress message - ", error);
return;
}
if (msg.messageType && msg.messageType === 'hello') {
this._handshakeComplete = true;
this._onSuccess();
}
},
/**
* Create a JSON message payload and send on websocket.
*
* @param {Object} aMsg Message to send.
*/
_send: function(aMsg) {
if (!this._handshakeComplete) {
console.warn("MozLoopService::_send error - handshake not complete");
return;
}
try {
this._websocket.sendMsg(JSON.stringify(aMsg));
}
catch (error) {
this._onError(error);
}
},
/**
* Notifies the server that the user has declined the call
* with a reason of busy.
*/
sendBusy: function() {
this._send({
messageType: "action",
event: "terminate",
reason: "busy"
});
},
};
/**
* Internal helper methods and state
*
@ -89,7 +242,7 @@ let gErrors = new Map();
* and register with the Loop server.
*/
let MozLoopServiceInternal = {
callsData: {data: undefined},
callsData: {inUse: false},
// The uri of the Loop server.
get loopServerUri() Services.prefs.getCharPref("loop.server"),
@ -243,10 +396,19 @@ let MozLoopServiceInternal = {
2 * 32, true);
}
return gHawkClient.request(path, method, credentials, payloadObj).catch(error => {
console.error("Loop hawkRequest error:", error);
throw error;
});
return gHawkClient.request(path, method, credentials, payloadObj);
},
/**
* Generic hawkRequest onError handler for the hawkRequest promise.
*
* @param {Object} error - error reporting object
*
*/
_hawkRequestError: function(error) {
console.error("Loop hawkRequest error:", error);
throw error;
},
getSessionTokenPrefName: function(sessionType) {
@ -422,23 +584,84 @@ let MozLoopServiceInternal = {
// bug 1046039 for background.
Services.prefs.setCharPref("loop.seenToS", "seen");
/* Request the information on the new call(s) associated with this version. */
this.hawkRequest(LOOP_SESSION_TYPE.GUEST,
"/calls?version=" + version, "GET").then(response => {
try {
let respData = JSON.parse(response.body);
if (respData.calls && respData.calls[0]) {
this.callsData.data = respData.calls[0];
this.openChatWindow(null,
this.localizedStrings["incoming_call_title2"].textContent,
"about:loopconversation#incoming/" + version);
} else {
console.warn("Error: missing calls[] in response");
}
} catch (err) {
console.warn("Error parsing calls info", err);
// Request the information on the new call(s) associated with this version.
// The registered FxA session is checked first, then the anonymous session.
// Make the call to get the GUEST session regardless of whether the FXA
// request fails.
this._getCalls(LOOP_SESSION_TYPE.FXA, version).catch(() => {});
this._getCalls(LOOP_SESSION_TYPE.GUEST, version).catch(
error => {this._hawkRequestError(error);});
},
/**
* Make a hawkRequest to GET/calls?=version for this session type.
*
* @param {LOOP_SESSION_TYPE} sessionType - type of hawk token used
* for the GET operation.
* @param {Object} version - LoopPushService notification version
*
* @returns {Promise}
*
*/
_getCalls: function(sessionType, version) {
return this.hawkRequest(sessionType, "/calls?version=" + version, "GET").then(
response => {this._processCalls(response, sessionType);}
);
},
/**
* Process the calls array returned from a GET/calls?version request.
* Only one active call is permitted at this time.
*
* @param {Object} response - response payload from GET
*
* @param {LOOP_SESSION_TYPE} sessionType - type of hawk token used
* for the GET operation.
*
*/
_processCalls: function(response, sessionType) {
try {
let respData = JSON.parse(response.body);
if (respData.calls && Array.isArray(respData.calls)) {
respData.calls.forEach((callData) => {
if (!this.callsData.inUse) {
this.callsData.inUse = true;
callData.sessionType = sessionType;
this.callsData.data = callData;
this.openChatWindow(
null,
this.localizedStrings["incoming_call_title2"].textContent,
"about:loopconversation#incoming/" + callData.callId);
} else {
this._returnBusy(callData);
}
});
} else {
console.warn("Error: missing calls[] in response");
}
});
} catch (err) {
console.warn("Error parsing calls info", err);
}
},
/**
* Open call progress websocket and terminate with a reason of busy
* the server.
*
* @param {callData} Must contain the progressURL, callId and websocketToken
* returned by the LoopService.
*/
_returnBusy: function(callData) {
let callProgress = new CallProgressSocket(
callData.progressURL,
callData.callId,
callData.websocketToken);
// This instance of CallProgressSocket should stay alive until the underlying
// websocket is closed since it is passed to the websocket as the nsIWebSocketListener.
callProgress.connect(() => {callProgress.sendBusy();});
},
/**
@ -619,7 +842,8 @@ let MozLoopServiceInternal = {
}
return JSON.parse(response.body);
});
},
error => {this._hawkRequestError(error);});
},
/**
@ -697,7 +921,8 @@ let MozLoopServiceInternal = {
};
return this.hawkRequest(LOOP_SESSION_TYPE.FXA, "/fxa-oauth/token", "POST", payload).then(response => {
return JSON.parse(response.body);
});
},
error => {this._hawkRequestError(error);});
},
/**
@ -959,7 +1184,7 @@ this.MozLoopService = {
},
/**
* Returns the callData for a specific callDataId
* Returns the callData for a specific loopCallId
*
* The data was retrieved from the LoopServer via a GET/calls/<version> request
* triggered by an incoming message from the LoopPushServer.
@ -968,7 +1193,27 @@ this.MozLoopService = {
* @return {callData} The callData or undefined if error.
*/
getCallData: function(loopCallId) {
return MozLoopServiceInternal.callsData.data;
if (MozLoopServiceInternal.callsData.data &&
MozLoopServiceInternal.callsData.data.callId == loopCallId) {
return MozLoopServiceInternal.callsData.data;
} else {
return undefined;
}
},
/**
* Releases the callData for a specific loopCallId
*
* The result of this call will be a free call session slot.
*
* @param {int} loopCallId
*/
releaseCallData: function(loopCallId) {
if (MozLoopServiceInternal.callsData.data &&
MozLoopServiceInternal.callsData.data.callId == loopCallId) {
MozLoopServiceInternal.callsData.data = undefined;
MozLoopServiceInternal.callsData.inUse = false;
}
},
/**
@ -1121,6 +1366,7 @@ this.MozLoopService = {
* rejected with this JSON-parsed response.
*/
hawkRequest: function(sessionType, path, method, payloadObj) {
return MozLoopServiceInternal.hawkRequest(sessionType, path, method, payloadObj);
return MozLoopServiceInternal.hawkRequest(sessionType, path, method, payloadObj).catch(
error => {this._hawkRequestError(error);});
},
};

Просмотреть файл

@ -215,6 +215,7 @@ loop.conversation = (function(OT, mozL10n) {
"call/decline": "decline",
"call/ongoing": "conversation",
"call/declineAndBlock": "declineAndBlock",
"call/shutdown": "shutdown",
"call/feedback": "feedback"
},
@ -229,9 +230,14 @@ loop.conversation = (function(OT, mozL10n) {
* @override {loop.shared.router.BaseConversationRouter.endCall}
*/
endCall: function() {
navigator.mozLoop.releaseCallData(this._conversation.get("callId"));
this.navigate("call/feedback", {trigger: true});
},
shutdown: function() {
navigator.mozLoop.releaseCallData(this._conversation.get("callId"));
},
/**
* Incoming call route.
*
@ -348,6 +354,7 @@ loop.conversation = (function(OT, mozL10n) {
*/
_declineCall: function() {
this._websocket.decline();
navigator.mozLoop.releaseCallData(this._conversation.get("callId"));
// XXX Don't close the window straight away, but let any sends happen
// first. Ideally we'd wait to close the window until after we have a
// response from the server, to know that everything has completed
@ -458,6 +465,12 @@ loop.conversation = (function(OT, mozL10n) {
{sdk: OT}), // Model dependencies
notifications: new loop.shared.models.NotificationCollection()
});
window.addEventListener("unload", (event) => {
// Handle direct close of dialog box via [x] control.
navigator.mozLoop.releaseCallData(router._conversation.get("callId"));
});
Backbone.history.start();
}

Просмотреть файл

@ -215,6 +215,7 @@ loop.conversation = (function(OT, mozL10n) {
"call/decline": "decline",
"call/ongoing": "conversation",
"call/declineAndBlock": "declineAndBlock",
"call/shutdown": "shutdown",
"call/feedback": "feedback"
},
@ -229,9 +230,14 @@ loop.conversation = (function(OT, mozL10n) {
* @override {loop.shared.router.BaseConversationRouter.endCall}
*/
endCall: function() {
navigator.mozLoop.releaseCallData(this._conversation.get("callId"));
this.navigate("call/feedback", {trigger: true});
},
shutdown: function() {
navigator.mozLoop.releaseCallData(this._conversation.get("callId"));
},
/**
* Incoming call route.
*
@ -348,6 +354,7 @@ loop.conversation = (function(OT, mozL10n) {
*/
_declineCall: function() {
this._websocket.decline();
navigator.mozLoop.releaseCallData(this._conversation.get("callId"));
// XXX Don't close the window straight away, but let any sends happen
// first. Ideally we'd wait to close the window until after we have a
// response from the server, to know that everything has completed
@ -458,6 +465,12 @@ loop.conversation = (function(OT, mozL10n) {
{sdk: OT}), // Model dependencies
notifications: new loop.shared.models.NotificationCollection()
});
window.addEventListener("unload", (event) => {
// Handle direct close of dialog box via [x] control.
navigator.mozLoop.releaseCallData(router._conversation.get("callId"));
});
Backbone.history.start();
}

Просмотреть файл

@ -18,9 +18,9 @@ loop.shared.models = (function(l10n) {
ongoing: false, // Ongoing call flag
callerId: undefined, // Loop caller id
loopToken: undefined, // Loop conversation token
loopCallId: undefined, // LoopService id for incoming session
sessionId: undefined, // OT session id
sessionToken: undefined, // OT session token
sessionType: undefined, // Hawk session type
apiKey: undefined, // OT api key
callId: undefined, // The callId on the server
progressURL: undefined, // The websocket url to use for progress
@ -139,6 +139,7 @@ loop.shared.models = (function(l10n) {
this.set({
sessionId: sessionData.sessionId,
sessionToken: sessionData.sessionToken,
sessionType: sessionData.sessionType,
apiKey: sessionData.apiKey,
callId: sessionData.callId,
progressURL: sessionData.progressURL,

Просмотреть файл

@ -30,6 +30,7 @@ describe("loop.conversation", function() {
getLoopCharPref: sandbox.stub(),
getLoopBoolPref: sandbox.stub(),
getCallData: sandbox.stub(),
releaseCallData: function() {},
startAlerting: function() {},
stopAlerting: function() {},
ensureRegistered: function() {},
@ -461,6 +462,10 @@ describe("loop.conversation", function() {
router._websocket = {
decline: sandbox.spy()
};
conversation.setIncomingSessionData({
callId: 8699,
websocketToken: 123
});
});
it("should close the window", function() {
@ -476,6 +481,14 @@ describe("loop.conversation", function() {
sinon.assert.calledOnce(navigator.mozLoop.stopAlerting);
});
it("should release callData", function() {
sandbox.stub(navigator.mozLoop, "releaseCallData");
router.decline();
sinon.assert.calledOnce(navigator.mozLoop.releaseCallData);
sinon.assert.calledWithExactly(navigator.mozLoop.releaseCallData, 8699);
});
});
describe("#feedback", function() {
@ -546,8 +559,9 @@ describe("loop.conversation", function() {
sandbox.stub(conversation, "get");
router.declineAndBlock();
sinon.assert.calledOnce(conversation.get);
sinon.assert.calledTwice(conversation.get);
sinon.assert.calledWithExactly(conversation.get, "callToken");
sinon.assert.calledWithExactly(conversation.get, "callId");
});
it("should trigger error handling in case of error", function() {

Просмотреть файл

@ -372,11 +372,13 @@ this.PlacesUIUtils = {
if (this.PLACES_FLAVORS.indexOf(aData.type) == -1)
throw new Error (`itemGuid unexpectedly set on ${aData.type} data`);
let info = { GUID: aData.itemGuid
, newParentGUID: aNewParentGuid
let info = { guid: aData.itemGuid
, newParentGuid: aNewParentGuid
, newIndex: aIndex };
if (aCopy)
if (aCopy) {
info.excludingAnnotation = "Places/SmartBookmark";
return PlacesTransactions.Copy(info);
}
return PlacesTransactions.Move(info);
}
@ -388,7 +390,7 @@ this.PlacesUIUtils = {
throw new Error("Can't copy a container from a legacy-transactions build");
if (aData.type == PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR) {
return PlacesTransactions.NewSeparator({ parentGUID: aNewParentGuid
return PlacesTransactions.NewSeparator({ parentGuid: aNewParentGuid
, index: aIndex });
}
@ -396,7 +398,7 @@ this.PlacesUIUtils = {
: aData.uri;
return PlacesTransactions.NewBookmark({ uri: NetUtil.newURI(aData.uri)
, title: title
, parentGUID: aNewParentGuid
, parentGuid: aNewParentGuid
, index: aIndex });
},

Просмотреть файл

@ -57,7 +57,7 @@ InsertionPoint.prototype = {
return this._index = val;
},
promiseGuid: function () PlacesUtils.promiseItemGUID(this.itemId),
promiseGuid: function () PlacesUtils.promiseItemGuid(this.itemId),
get index() {
if (this.dropNearItemId > 0) {
@ -781,7 +781,7 @@ PlacesController.prototype = {
return;
}
let txn = PlacesTransactions.NewSeparator({ parentGUID: yield ip.promiseGuid()
let txn = PlacesTransactions.NewSeparator({ parentGuid: yield ip.promiseGuid()
, index: ip.index });
let guid = yield PlacesTransactions.transact(txn);
let itemId = yield PlacesUtils.promiseItemId(guid);
@ -808,7 +808,7 @@ PlacesController.prototype = {
PlacesUtils.transactionManager.doTransaction(txn);
return;
}
let guid = yield PlacesUtils.promiseItemGUID(itemId);
let guid = yield PlacesUtils.promiseItemGuid(itemId);
yield PlacesTransactions.transact(PlacesTransactions.SortByName(guid));
}),

Просмотреть файл

@ -46,13 +46,13 @@ var gMoveBookmarksDialog = {
}
PlacesTransactions.transact(function* () {
let newParentGUID = yield PlacesUtils.promiseItemGUID(selectedFolderId);
let newParentGuid = yield PlacesUtils.promiseItemGuid(selectedFolderId);
for (let node of this._nodes) {
// Nothing to do if the node is already under the selected folder.
if (node.parent.itemId == selectedFolderId)
continue;
yield PlacesTransactions.Move({ GUID: node.bookmarkGuid
, newParentGUID: newParentGUID });
yield PlacesTransactions.Move({ guid: node.bookmarkGuid
, newParentGuid: newParentGuid });
}
}.bind(this)).then(null, Components.utils.reportError);
},

Просмотреть файл

@ -7,10 +7,9 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { target, panel } = yield initShaderEditor(SIMPLE_CANVAS_URL);
ok(target, "Should have a target available.");
ok(debuggee, "Should have a debuggee available.");
ok(panel, "Should have a panel available.");
yield teardown(panel);

Просмотреть файл

@ -5,7 +5,7 @@
* Tests if the shader editor works with bfcache.
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { target, panel } = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { gFront, $, EVENTS, ShadersListView, ShadersEditorsView } = panel.panelWin;
// Attach frame scripts if in e10s to perform

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { target, panel } = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { gFront, ShadersEditorsView, EVENTS } = panel.panelWin;
reload(target);

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { target, panel } = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { gFront, EVENTS, ShadersEditorsView } = panel.panelWin;
reload(target);

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { target, panel } = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { gFront, EVENTS, ShadersEditorsView } = panel.panelWin;
reload(target);

Просмотреть файл

@ -6,7 +6,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { target, panel } = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { gFront, ShadersEditorsView } = panel.panelWin;
try {

Просмотреть файл

@ -6,7 +6,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { target, panel } = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { gFront, $ } = panel.panelWin;
is($("#reload-notice").hidden, false,

Просмотреть файл

@ -6,7 +6,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { target, panel } = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { gFront, $, EVENTS, ShadersListView, ShadersEditorsView } = panel.panelWin;
reload(target);

Просмотреть файл

@ -6,7 +6,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(MULTIPLE_CONTEXTS_URL);
let { target, debuggee, panel } = yield initShaderEditor(MULTIPLE_CONTEXTS_URL);
let { gFront, EVENTS, ShadersListView, ShadersEditorsView } = panel.panelWin;
once(panel.panelWin, EVENTS.SHADER_COMPILED).then(() => {

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(BLENDED_GEOMETRY_CANVAS_URL);
let { target, debuggee, panel } = yield initShaderEditor(BLENDED_GEOMETRY_CANVAS_URL);
let { gFront, EVENTS, ShadersListView, ShadersEditorsView } = panel.panelWin;
reload(target);

Просмотреть файл

@ -6,7 +6,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(MULTIPLE_CONTEXTS_URL);
let { target, debuggee, panel } = yield initShaderEditor(MULTIPLE_CONTEXTS_URL);
let { EVENTS, gFront, ShadersListView, ShadersEditorsView } = panel.panelWin;
reload(target);

Просмотреть файл

@ -6,7 +6,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(MULTIPLE_CONTEXTS_URL);
let { target, panel } = yield initShaderEditor(MULTIPLE_CONTEXTS_URL);
let { gFront, EVENTS, ShadersListView, ShadersEditorsView } = panel.panelWin;
once(panel.panelWin, EVENTS.SHADER_COMPILED).then(() => {

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(BLENDED_GEOMETRY_CANVAS_URL);
let { target, debuggee, panel } = yield initShaderEditor(BLENDED_GEOMETRY_CANVAS_URL);
let { gFront, EVENTS, ShadersListView, ShadersEditorsView } = panel.panelWin;
reload(target);

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(MULTIPLE_CONTEXTS_URL);
let { target, panel } = yield initShaderEditor(MULTIPLE_CONTEXTS_URL);
let { gFront, EVENTS, L10N, ShadersListView, ShadersEditorsView } = panel.panelWin;
is(ShadersListView.itemCount, 0,

Просмотреть файл

@ -6,7 +6,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { target, panel } = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { gFront, $, EVENTS, ShadersEditorsView } = panel.panelWin;
reload(target);

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { target, panel } = yield initShaderEditor(SIMPLE_CANVAS_URL);
let { gFront, EVENTS, ShadersEditorsView } = panel.panelWin;
reload(target);

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, panel] = yield initShaderEditor(MULTIPLE_CONTEXTS_URL);
let { target, panel } = yield initShaderEditor(MULTIPLE_CONTEXTS_URL);
let { gFront, EVENTS, ShadersListView, ShadersEditorsView } = panel.panelWin;
reload(target);

Просмотреть файл

@ -6,10 +6,9 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SIMPLE_CANVAS_URL);
let { target, front } = yield initBackend(SIMPLE_CANVAS_URL);
ok(target, "Should have a target available.");
ok(debuggee, "Should have a debuggee available.");
ok(front, "Should have a protocol front available.");
yield removeTab(target.tab);

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SIMPLE_CANVAS_URL);
let { target, front } = yield initBackend(SIMPLE_CANVAS_URL);
once(front, "program-linked").then(() => {
ok(false, "A 'program-linked' notification shouldn't have been sent!");

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SIMPLE_CANVAS_URL);
let { target, front } = yield initBackend(SIMPLE_CANVAS_URL);
let navigated = once(target, "navigate");
let linked = once(front, "program-linked");

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SIMPLE_CANVAS_URL);
let { target, front } = yield initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
let programActor = yield once(front, "program-linked");

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SIMPLE_CANVAS_URL);
let { target, front } = yield initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
let programActor = yield once(front, "program-linked");

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SIMPLE_CANVAS_URL);
let { target, front } = yield initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
let programActor = yield once(front, "program-linked");

Просмотреть файл

@ -6,7 +6,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SIMPLE_CANVAS_URL);
let { target, front } = yield initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
let programActor = yield once(front, "program-linked");

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SIMPLE_CANVAS_URL);
let { target, front } = yield initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
let programActor = yield once(front, "program-linked");

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SIMPLE_CANVAS_URL);
let { target, front } = yield initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
let programActor = yield once(front, "program-linked");

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SIMPLE_CANVAS_URL);
let { target, front } = yield initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
yield testHighlighting((yield once(front, "program-linked")));

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SIMPLE_CANVAS_URL);
let { target, front } = yield initBackend(SIMPLE_CANVAS_URL);
let linked = once(front, "program-linked");
front.setup({ reload: true });

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SHADER_ORDER_URL);
let { target, front } = yield initBackend(SHADER_ORDER_URL);
front.setup({ reload: true });
let programActor = yield once(front, "program-linked");

Просмотреть файл

@ -6,7 +6,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(MULTIPLE_CONTEXTS_URL);
let { target, front } = yield initBackend(MULTIPLE_CONTEXTS_URL);
front.setup({ reload: true });
let [firstProgramActor, secondProgramActor] = yield getPrograms(front, 2);

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(MULTIPLE_CONTEXTS_URL);
let { target, front } = yield initBackend(MULTIPLE_CONTEXTS_URL);
front.setup({ reload: true });
let [firstProgramActor, secondProgramActor] = yield getPrograms(front, 2);

Просмотреть файл

@ -6,7 +6,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SIMPLE_CANVAS_URL);
let { target, front } = yield initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: false });
// Attach frame scripts if in e10s to perform

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(SIMPLE_CANVAS_URL);
let { target, front } = yield initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: false });
// Attach frame scripts if in e10s to perform

Просмотреть файл

@ -7,7 +7,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(OVERLAPPING_GEOMETRY_CANVAS_URL);
let { target, front } = yield initBackend(OVERLAPPING_GEOMETRY_CANVAS_URL);
front.setup({ reload: true });
let [firstProgramActor, secondProgramActor] = yield getPrograms(front, 2);

Просмотреть файл

@ -6,7 +6,7 @@
*/
function ifWebGLSupported() {
let [target, debuggee, front] = yield initBackend(MULTIPLE_CONTEXTS_URL);
let { target, front } = yield initBackend(MULTIPLE_CONTEXTS_URL);
front.setup({ reload: true });
yield getPrograms(front, 2);

Просмотреть файл

@ -241,12 +241,11 @@ function initBackend(aUrl) {
return Task.spawn(function*() {
let tab = yield addTab(aUrl);
let target = TargetFactory.forTab(tab);
let debuggee = target.window.wrappedJSObject;
yield target.makeRemote();
let front = new WebGLFront(target.client, target.form);
return [target, debuggee, front];
return { target, front };
});
}
@ -256,14 +255,13 @@ function initShaderEditor(aUrl) {
return Task.spawn(function*() {
let tab = yield addTab(aUrl);
let target = TargetFactory.forTab(tab);
let debuggee = target.window.wrappedJSObject;
yield target.makeRemote();
Services.prefs.setBoolPref("devtools.shadereditor.enabled", true);
let toolbox = yield gDevTools.showToolbox(target, "shadereditor");
let panel = toolbox.getCurrentPanel();
return [target, debuggee, panel];
return { target, panel };
});
}

Просмотреть файл

@ -1,5 +1,4 @@
[DEFAULT]
skip-if = e10s # Bug 1065355 - devtools tests disabled with e10s
subsuite = devtools
support-files =
doc_simple-test.html

Просмотреть файл

@ -7,10 +7,9 @@
*/
let test = Task.async(function*() {
let [target, debuggee, panel] = yield initTimelinePanel(SIMPLE_URL);
let { target, panel } = yield initTimelinePanel(SIMPLE_URL);
ok(target, "Should have a target available.");
ok(debuggee, "Should have a debuggee available.");
ok(panel, "Should have a panel available.");
ok(panel.panelWin.gToolbox, "Should have a toolbox reference on the panel window.");

Просмотреть файл

@ -7,7 +7,7 @@
*/
let test = Task.async(function*() {
let [target, debuggee, panel] = yield initTimelinePanel(SIMPLE_URL);
let { target, panel } = yield initTimelinePanel(SIMPLE_URL);
let { EVENTS, TimelineView, TimelineController } = panel.panelWin;
let { OVERVIEW_INITIAL_SELECTION_RATIO: selectionRatio } = panel.panelWin;

Просмотреть файл

@ -7,7 +7,7 @@
*/
let test = Task.async(function*() {
let [target, debuggee, panel] = yield initTimelinePanel(SIMPLE_URL);
let { target, panel } = yield initTimelinePanel(SIMPLE_URL);
let { EVENTS, TimelineView, TimelineController } = panel.panelWin;
let { OVERVIEW_INITIAL_SELECTION_RATIO: selectionRatio } = panel.panelWin;

Просмотреть файл

@ -6,7 +6,7 @@
*/
let test = Task.async(function*() {
let [target, debuggee, panel] = yield initTimelinePanel("about:blank");
let { target, panel } = yield initTimelinePanel("about:blank");
let { EVENTS, TimelineView, TimelineController } = panel.panelWin;
yield DevToolsUtils.waitForTime(1000);

Просмотреть файл

@ -7,7 +7,7 @@
*/
let test = Task.async(function*() {
let [target, debuggee, panel] = yield initTimelinePanel(SIMPLE_URL);
let { target, panel } = yield initTimelinePanel(SIMPLE_URL);
let { $, EVENTS } = panel.panelWin;
is($("#record-button").hasAttribute("checked"), false,

Просмотреть файл

@ -6,7 +6,7 @@
*/
let test = Task.async(function*() {
let [target, debuggee, panel] = yield initTimelinePanel(SIMPLE_URL);
let { target, panel } = yield initTimelinePanel(SIMPLE_URL);
let { gFront, TimelineController } = panel.panelWin;
is((yield gFront.isRecording()), false,

Просмотреть файл

@ -7,7 +7,7 @@
*/
let test = Task.async(function*() {
let [target, debuggee, panel] = yield initTimelinePanel(SIMPLE_URL);
let { target, panel } = yield initTimelinePanel(SIMPLE_URL);
let { $, EVENTS, TimelineView, TimelineController } = panel.panelWin;
yield TimelineController.toggleRecording();

Просмотреть файл

@ -6,7 +6,7 @@
*/
let test = Task.async(function*() {
let [target, debuggee, panel] = yield initTimelinePanel(SIMPLE_URL);
let { target, panel } = yield initTimelinePanel(SIMPLE_URL);
let { $, $$, EVENTS, TimelineController } = panel.panelWin;
yield TimelineController.toggleRecording();

Просмотреть файл

@ -16,7 +16,7 @@ var gRGB_TO_HSL = {
};
let test = Task.async(function*() {
let [target, debuggee, panel] = yield initTimelinePanel(SIMPLE_URL);
let { target, panel } = yield initTimelinePanel(SIMPLE_URL);
let { TIMELINE_BLUEPRINT } = devtools.require("devtools/timeline/global");
let { $, $$, EVENTS, TimelineController } = panel.panelWin;

Просмотреть файл

@ -78,20 +78,19 @@ function removeTab(tab) {
* The location of the new tab to spawn.
* @return object
* A promise resolved once the timeline is initialized, with the
* [target, debuggee, panel] instances.
* {target, panel} instances.
*/
function* initTimelinePanel(url) {
info("Initializing a timeline pane.");
let tab = yield addTab(url);
let target = TargetFactory.forTab(tab);
let debuggee = target.window.wrappedJSObject;
yield target.makeRemote();
let toolbox = yield gDevTools.showToolbox(target, "timeline");
let panel = toolbox.getCurrentPanel();
return [target, debuggee, panel];
return { target, panel };
}
/**

Просмотреть файл

@ -1,4 +1,4 @@
This is the pdf.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 1.0.712
Current extension version is: 1.0.801

Просмотреть файл

@ -42,6 +42,10 @@ XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
XPCOMUtils.defineLazyServiceGetter(Svc, 'pluginHost',
'@mozilla.org/plugin/host;1',
'nsIPluginHost');
XPCOMUtils.defineLazyModuleGetter(this, "PdfjsChromeUtils",
"resource://pdf.js/PdfjsChromeUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PdfjsContentUtils",
"resource://pdf.js/PdfjsContentUtils.jsm");
function getBoolPref(aPref, aDefaultValue) {
try {
@ -59,6 +63,13 @@ function getIntPref(aPref, aDefaultValue) {
}
}
function isDefaultHandler() {
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
return PdfjsContentUtils.isDefaultHandlerApp();
}
return PdfjsChromeUtils.isDefaultHandlerApp();
}
function initializeDefaultPreferences() {
var DEFAULT_PREFERENCES = {
@ -118,17 +129,30 @@ Factory.prototype = {
let PdfJs = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
_registered: false,
_initialized: false,
init: function init(remote) {
if (Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_DEFAULT) {
throw new Error("PdfJs.init should only get called in the parent process.");
}
PdfjsChromeUtils.init();
if (!remote) {
PdfjsContentUtils.init();
}
this.initPrefs();
this.updateRegistration();
},
initPrefs: function initPrefs() {
if (this._initialized) {
return;
}
this._initialized = true;
init: function init() {
if (!getBoolPref(PREF_DISABLED, true)) {
this._migrate();
}
if (this.enabled)
this._ensureRegistered();
else
this._ensureUnregistered();
// Listen for when pdf.js is completely disabled or a different pdf handler
// is chosen.
Services.prefs.addObserver(PREF_DISABLED, this, false);
@ -140,6 +164,26 @@ let PdfJs = {
initializeDefaultPreferences();
},
updateRegistration: function updateRegistration() {
if (this.enabled) {
this._ensureRegistered();
} else {
this._ensureUnregistered();
}
},
uninit: function uninit() {
if (this._initialized) {
Services.prefs.removeObserver(PREF_DISABLED, this, false);
Services.prefs.removeObserver(PREF_DISABLED_PLUGIN_TYPES, this, false);
Services.obs.removeObserver(this, TOPIC_PDFJS_HANDLER_CHANGED, false);
Services.obs.removeObserver(this, TOPIC_PLUGINS_LIST_UPDATED, false);
Services.obs.removeObserver(this, TOPIC_PLUGIN_INFO_UPDATED, false);
this._initialized = false;
}
this._ensureUnregistered();
},
_migrate: function migrate() {
const VERSION = 2;
var currentVersion = getIntPref(PREF_MIGRATION_VERSION, 0);
@ -202,10 +246,12 @@ let PdfJs = {
// nsIObserver
observe: function observe(aSubject, aTopic, aData) {
if (this.enabled)
this._ensureRegistered();
else
this._ensureUnregistered();
this.updateRegistration();
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_DEFAULT) {
let jsm = "resource://pdf.js/PdfjsChromeUtils.jsm";
let PdfjsChromeUtils = Components.utils.import(jsm, {}).PdfjsChromeUtils;
PdfjsChromeUtils.notifyChildOfSettingsChange();
}
},
/**
@ -219,11 +265,8 @@ let PdfJs = {
return false;
}
// the 'application/pdf' handler is selected as internal?
var handlerInfo = Svc.mime
.getFromTypeAndExtension(PDF_CONTENT_TYPE, 'pdf');
if (handlerInfo.alwaysAskBeforeHandling ||
handlerInfo.preferredAction !== Ci.nsIHandlerInfo.handleInternally) {
// Check if the 'application/pdf' preview handler is configured properly.
if (!isDefaultHandler()) {
return false;
}

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2013 Mozilla Foundation
*

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2012 Mozilla Foundation
*

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2012 Mozilla Foundation
*
@ -48,6 +48,9 @@ XPCOMUtils.defineLazyModuleGetter(this, 'PrivateBrowsingUtils',
XPCOMUtils.defineLazyModuleGetter(this, 'PdfJsTelemetry',
'resource://pdf.js/PdfJsTelemetry.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'PdfjsContentUtils',
'resource://pdf.js/PdfjsContentUtils.jsm');
var Svc = {};
XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
'@mozilla.org/mime;1',
@ -61,10 +64,16 @@ function getContainingBrowser(domWindow) {
}
function getChromeWindow(domWindow) {
if (PdfjsContentUtils.isRemote) {
return PdfjsContentUtils.getChromeWindow(domWindow);
}
return getContainingBrowser(domWindow).ownerDocument.defaultView;
}
function getFindBar(domWindow) {
if (PdfjsContentUtils.isRemote) {
return PdfjsContentUtils.getFindBar(domWindow);
}
var browser = getContainingBrowser(domWindow);
try {
var tabbrowser = browser.getTabBrowser();
@ -77,10 +86,6 @@ function getFindBar(domWindow) {
}
}
function setBoolPref(pref, value) {
Services.prefs.setBoolPref(pref, value);
}
function getBoolPref(pref, def) {
try {
return Services.prefs.getBoolPref(pref);
@ -89,10 +94,6 @@ function getBoolPref(pref, def) {
}
}
function setIntPref(pref, value) {
Services.prefs.setIntPref(pref, value);
}
function getIntPref(pref, def) {
try {
return Services.prefs.getIntPref(pref);
@ -101,13 +102,6 @@ function getIntPref(pref, def) {
}
}
function setStringPref(pref, value) {
var str = Cc['@mozilla.org/supports-string;1']
.createInstance(Ci.nsISupportsString);
str.data = value;
Services.prefs.setComplexValue(pref, Ci.nsISupportsString, str);
}
function getStringPref(pref, def) {
try {
return Services.prefs.getComplexValue(pref, Ci.nsISupportsString).data;
@ -117,8 +111,9 @@ function getStringPref(pref, def) {
}
function log(aMsg) {
if (!getBoolPref(PREF_PREFIX + '.pdfBugEnabled', false))
if (!getBoolPref(PREF_PREFIX + '.pdfBugEnabled', false)) {
return;
}
var msg = 'PdfStreamConverter.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
Services.console.logStringMessage(msg);
dump(msg + '\n');
@ -423,53 +418,10 @@ ChromeActions.prototype = {
} else {
message = getLocalizedString(strings, 'unsupported_feature');
}
PdfJsTelemetry.onFallback();
var notificationBox = null;
try {
// Based on MDN's "Working with windows in chrome code"
var mainWindow = domWindow
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow);
var browser = mainWindow.gBrowser
.getBrowserForDocument(domWindow.top.document);
notificationBox = mainWindow.gBrowser.getNotificationBox(browser);
} catch (e) {
log('Unable to get a notification box for the fallback message');
return;
}
// Flag so we don't call the response callback twice, since if the user
// clicks open with different viewer both the button callback and
// eventCallback will be called.
var sentResponse = false;
var buttons = [{
label: getLocalizedString(strings, 'open_with_different_viewer'),
accessKey: getLocalizedString(strings, 'open_with_different_viewer',
'accessKey'),
callback: function() {
sentResponse = true;
sendResponse(true);
}
}];
notificationBox.appendNotification(message, 'pdfjs-fallback', null,
notificationBox.PRIORITY_INFO_LOW,
buttons,
function eventsCallback(eventType) {
// Currently there is only one event "removed" but if there are any other
// added in the future we still only care about removed at the moment.
if (eventType !== 'removed')
return;
// Don't send a response again if we already responded when the button was
// clicked.
if (!sentResponse)
sendResponse(false);
});
PdfjsContentUtils.displayWarning(domWindow, message, sendResponse,
getLocalizedString(strings, 'open_with_different_viewer'),
getLocalizedString(strings, 'open_with_different_viewer', 'accessKey'));
},
updateFindControlState: function(data) {
if (!this.supportsIntegratedFind())
@ -500,17 +452,17 @@ ChromeActions.prototype = {
prefName = (PREF_PREFIX + '.' + key);
switch (typeof prefValue) {
case 'boolean':
setBoolPref(prefName, prefValue);
PdfjsContentUtils.setBoolPref(prefName, prefValue);
break;
case 'number':
setIntPref(prefName, prefValue);
PdfjsContentUtils.setIntPref(prefName, prefValue);
break;
case 'string':
if (prefValue.length > MAX_STRING_PREF_LENGTH) {
log('setPreferences - Exceeded the maximum allowed length ' +
'for a string preference.');
} else {
setStringPref(prefName, prefValue);
PdfjsContentUtils.setStringPref(prefName, prefValue);
}
break;
}
@ -793,7 +745,12 @@ FindEventManager.prototype.handleEvent = function(e) {
detail = makeContentReadable(detail, contentWindow);
var forward = contentWindow.document.createEvent('CustomEvent');
forward.initCustomEvent(e.type, true, true, detail);
contentWindow.dispatchEvent(forward);
// Due to restrictions with cpow use, we can't dispatch
// dom events with an urgent message on the stack. So bounce
// this off the main thread to make it async.
Services.tm.mainThread.dispatch(function () {
contentWindow.dispatchEvent(forward);
}, Ci.nsIThread.DISPATCH_NORMAL);
e.preventDefault();
}
};
@ -911,7 +868,6 @@ PdfStreamConverter.prototype = {
PdfJsTelemetry.onViewerIsUsed();
PdfJsTelemetry.onDocumentSize(aRequest.contentLength);
// Creating storage for PDF data
var contentLength = aRequest.contentLength;
this.dataListener = new PdfDataListener(contentLength);

Просмотреть файл

@ -0,0 +1,328 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2012 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*globals DEFAULT_PREFERENCES */
'use strict';
var EXPORTED_SYMBOLS = ['PdfjsChromeUtils'];
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
const PREF_PREFIX = 'pdfjs';
const PDF_CONTENT_TYPE = 'application/pdf';
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
let Svc = {};
XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
'@mozilla.org/mime;1',
'nsIMIMEService');
var DEFAULT_PREFERENCES = {
showPreviousViewOnLoad: true,
defaultZoomValue: '',
sidebarViewOnLoad: 0,
enableHandToolOnLoad: false,
enableWebGL: false,
disableRange: false,
disableAutoFetch: false,
disableFontFace: false,
disableTextLayer: false,
useOnlyCssZoom: false
};
let PdfjsChromeUtils = {
// For security purposes when running remote, we restrict preferences
// content can access.
_allowedPrefNames: Object.keys(DEFAULT_PREFERENCES),
_ppmm: null,
_mmg: null,
/*
* Public API
*/
init: function () {
if (!this._ppmm) {
// global parent process message manager (PPMM)
this._ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIMessageBroadcaster);
this._ppmm.addMessageListener("PDFJS:Parent:clearUserPref", this);
this._ppmm.addMessageListener("PDFJS:Parent:setIntPref", this);
this._ppmm.addMessageListener("PDFJS:Parent:setBoolPref", this);
this._ppmm.addMessageListener("PDFJS:Parent:setCharPref", this);
this._ppmm.addMessageListener("PDFJS:Parent:setStringPref", this);
this._ppmm.addMessageListener("PDFJS:Parent:isDefaultHandlerApp", this);
// global dom message manager (MMg)
this._mmg = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
this._mmg.addMessageListener("PDFJS:Parent:getChromeWindow", this);
this._mmg.addMessageListener("PDFJS:Parent:getFindBar", this);
this._mmg.addMessageListener("PDFJS:Parent:displayWarning", this);
// observer to handle shutdown
Services.obs.addObserver(this, "quit-application", false);
}
},
uninit: function () {
if (this._ppmm) {
this._ppmm.removeMessageListener("PDFJS:Parent:clearUserPref", this);
this._ppmm.removeMessageListener("PDFJS:Parent:setIntPref", this);
this._ppmm.removeMessageListener("PDFJS:Parent:setBoolPref", this);
this._ppmm.removeMessageListener("PDFJS:Parent:setCharPref", this);
this._ppmm.removeMessageListener("PDFJS:Parent:setStringPref", this);
this._ppmm.removeMessageListener("PDFJS:Parent:isDefaultHandlerApp", this);
this._mmg.removeMessageListener("PDFJS:Parent:getChromeWindow", this);
this._mmg.removeMessageListener("PDFJS:Parent:getFindBar", this);
this._mmg.removeMessageListener("PDFJS:Parent:displayWarning", this);
Services.obs.removeObserver(this, "quit-application", false);
this._mmg = null;
this._ppmm = null;
}
},
/*
* Called by the main module when preference changes are picked up
* in the parent process. Observers don't propagate so we need to
* instruct the child to refresh its configuration and (possibly)
* the module's registration.
*/
notifyChildOfSettingsChange: function () {
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_DEFAULT &&
this._ppmm) {
// XXX kinda bad, we want to get the parent process mm associated
// with the content process. _ppmm is currently the global process
// manager, which means this is going to fire to every child process
// we have open. Unfortunately I can't find a way to get at that
// process specific mm from js.
this._ppmm.broadcastAsyncMessage("PDFJS:Child:refreshSettings", {});
}
},
/*
* Events
*/
observe: function(aSubject, aTopic, aData) {
if (aTopic == "quit-application") {
this.uninit();
}
},
receiveMessage: function (aMsg) {
switch (aMsg.name) {
case "PDFJS:Parent:clearUserPref":
this._clearUserPref(aMsg.data.name);
break;
case "PDFJS:Parent:setIntPref":
this._setIntPref(aMsg.data.name, aMsg.data.value);
break;
case "PDFJS:Parent:setBoolPref":
this._setBoolPref(aMsg.data.name, aMsg.data.value);
break;
case "PDFJS:Parent:setCharPref":
this._setCharPref(aMsg.data.name, aMsg.data.value);
break;
case "PDFJS:Parent:setStringPref":
this._setStringPref(aMsg.data.name, aMsg.data.value);
break;
case "PDFJS:Parent:isDefaultHandlerApp":
return this.isDefaultHandlerApp();
case "PDFJS:Parent:displayWarning":
this._displayWarning(aMsg);
break;
// CPOW getters
case "PDFJS:Parent:getChromeWindow":
return this._getChromeWindow(aMsg);
case "PDFJS:Parent:getFindBar":
return this._getFindBar(aMsg);
}
},
/*
* Internal
*/
_getChromeWindow: function (aMsg) {
// See the child module, our return result here can't be the element
// since return results don't get auto CPOW'd.
let browser = aMsg.target;
let wrapper = new PdfjsWindowWrapper(browser);
let suitcase = aMsg.objects.suitcase;
suitcase.setChromeWindow(wrapper);
return true;
},
_getFindBar: function (aMsg) {
// We send this over via the window's message manager, so target should
// be the dom window.
let browser = aMsg.target;
let wrapper = new PdfjsFindbarWrapper(browser);
let suitcase = aMsg.objects.suitcase;
suitcase.setFindBar(wrapper);
return true;
},
_ensurePreferenceAllowed: function (aPrefName) {
let unPrefixedName = aPrefName.split(PREF_PREFIX + '.');
if (unPrefixedName[0] !== '' ||
this._allowedPrefNames.indexOf(unPrefixedName[1]) === -1) {
let msg = "'" + aPrefName + "' ";
msg += "can't be accessed from content. See PdfjsChromeUtils."
throw new Error(msg);
}
},
_clearUserPref: function (aPrefName) {
this._ensurePreferenceAllowed(aPrefName);
Services.prefs.clearUserPref(aPrefName);
},
_setIntPref: function (aPrefName, aPrefValue) {
this._ensurePreferenceAllowed(aPrefName);
Services.prefs.setIntPref(aPrefName, aPrefValue);
},
_setBoolPref: function (aPrefName, aPrefValue) {
this._ensurePreferenceAllowed(aPrefName);
Services.prefs.setBoolPref(aPrefName, aPrefValue);
},
_setCharPref: function (aPrefName, aPrefValue) {
this._ensurePreferenceAllowed(aPrefName);
Services.prefs.setCharPref(aPrefName, aPrefValue);
},
_setStringPref: function (aPrefName, aPrefValue) {
this._ensurePreferenceAllowed(aPrefName);
let str = Cc['@mozilla.org/supports-string;1']
.createInstance(Ci.nsISupportsString);
str.data = aPrefValue;
Services.prefs.setComplexValue(aPrefName, Ci.nsISupportsString, str);
},
/*
* Svc.mime doesn't have profile information in the child, so
* we bounce this pdfjs enabled configuration check over to the
* parent.
*/
isDefaultHandlerApp: function () {
var handlerInfo = Svc.mime.getFromTypeAndExtension(PDF_CONTENT_TYPE, 'pdf');
return !handlerInfo.alwaysAskBeforeHandling &&
handlerInfo.preferredAction == Ci.nsIHandlerInfo.handleInternally;
},
/*
* Display a notification warning when the renderer isn't sure
* a pdf displayed correctly.
*/
_displayWarning: function (aMsg) {
let json = aMsg.data;
let browser = aMsg.target;
let cpowCallback = aMsg.objects.callback;
let tabbrowser = browser.getTabBrowser();
let notificationBox = tabbrowser.getNotificationBox(browser);
// Flag so we don't call the response callback twice, since if the user
// clicks open with different viewer both the button callback and
// eventCallback will be called.
let responseSent = false;
let buttons = [{
label: json.label,
accessKey: json.accessKey,
callback: function() {
responseSent = true;
cpowCallback(true);
}
}];
notificationBox.appendNotification(json.message, 'pdfjs-fallback', null,
notificationBox.PRIORITY_INFO_LOW,
buttons,
function eventsCallback(eventType) {
// Currently there is only one event "removed" but if there are any other
// added in the future we still only care about removed at the moment.
if (eventType !== 'removed') {
return;
}
// Don't send a response again if we already responded when the button was
// clicked.
if (responseSent) {
return;
}
cpowCallback(false);
});
}
};
/*
* CPOW security features require chrome objects declare exposed
* properties via __exposedProps__. We don't want to expose things
* directly on the findbar, so we wrap the findbar in a smaller
* object here that supports the features pdf.js needs.
*/
function PdfjsFindbarWrapper(aBrowser) {
let tabbrowser = aBrowser.getTabBrowser();
let tab = tabbrowser._getTabForBrowser(aBrowser);
this._findbar = tabbrowser.getFindBar(tab);
};
PdfjsFindbarWrapper.prototype = {
__exposedProps__: {
addEventListener: "r",
removeEventListener: "r",
updateControlState: "r",
},
_findbar: null,
updateControlState: function (aResult, aFindPrevious) {
this._findbar.updateControlState(aResult, aFindPrevious);
},
addEventListener: function (aType, aListener, aUseCapture, aWantsUntrusted) {
this._findbar.addEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
},
removeEventListener: function (aType, aListener, aUseCapture) {
this._findbar.removeEventListener(aType, aListener, aUseCapture);
}
};
function PdfjsWindowWrapper(aBrowser) {
this._window = aBrowser.ownerDocument.defaultView;
};
PdfjsWindowWrapper.prototype = {
__exposedProps__: {
valueOf: "r",
},
_window: null,
valueOf: function () {
return this._window.valueOf();
}
};

Просмотреть файл

@ -0,0 +1,193 @@
/* Copyright 2012 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
var EXPORTED_SYMBOLS = ['PdfjsContentUtils'];
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
let PdfjsContentUtils = {
_mm: null,
/*
* Public API
*/
get isRemote() {
return Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT;
},
init: function () {
// child *process* mm, or when loaded into the parent for in-content
// support the psuedo child process mm 'child PPMM'.
if (!this._mm) {
this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
this._mm.addMessageListener("PDFJS:Child:refreshSettings", this);
Services.obs.addObserver(this, "quit-application", false);
}
},
uninit: function () {
if (this._mm) {
this._mm.removeMessageListener("PDFJS:Child:refreshSettings", this);
Services.obs.removeObserver(this, "quit-application");
}
this._mm = null;
},
/*
* prefs utilities - the child does not have write access to prefs.
* note, the pref names here are cross-checked against a list of
* approved pdfjs prefs in chrome utils.
*/
clearUserPref: function (aPrefName) {
this._mm.sendSyncMessage("PDFJS:Parent:clearUserPref", {
name: aPrefName
});
},
setIntPref: function (aPrefName, aPrefValue) {
this._mm.sendSyncMessage("PDFJS:Parent:setIntPref", {
name: aPrefName,
value: aPrefValue
});
},
setBoolPref: function (aPrefName, aPrefValue) {
this._mm.sendSyncMessage("PDFJS:Parent:setBoolPref", {
name: aPrefName,
value: aPrefValue
});
},
setCharPref: function (aPrefName, aPrefValue) {
this._mm.sendSyncMessage("PDFJS:Parent:setCharPref", {
name: aPrefName,
value: aPrefValue
});
},
setStringPref: function (aPrefName, aPrefValue) {
this._mm.sendSyncMessage("PDFJS:Parent:setStringPref", {
name: aPrefName,
value: aPrefValue
});
},
/*
* Forwards default app query to the parent where we check various
* handler app settings only available in the parent process.
*/
isDefaultHandlerApp: function () {
return this._mm.sendSyncMessage("PDFJS:Parent:isDefaultHandlerApp")[0];
},
/*
* Request the display of a notification warning in the associated window
* when the renderer isn't sure a pdf displayed correctly.
*/
displayWarning: function (aWindow, aMessage, aCallback, aLabel, accessKey) {
// the child's dom frame mm associated with the window.
let winmm = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
winmm.sendAsyncMessage("PDFJS:Parent:displayWarning", {
message: aMessage,
label: aLabel,
accessKey: accessKey
}, {
callback: aCallback
});
},
/*
* Events
*/
observe: function(aSubject, aTopic, aData) {
if (aTopic == "quit-application") {
this.uninit();
}
},
receiveMessage: function (aMsg) {
switch (aMsg.name) {
case "PDFJS:Child:refreshSettings":
// Only react to this if we are remote.
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
let jsm = "resource://pdf.js/PdfJs.jsm";
let pdfjs = Components.utils.import(jsm, {}).PdfJs;
pdfjs.updateRegistration();
}
break;
}
},
/*
* CPOWs
*/
getChromeWindow: function (aWindow) {
let winmm = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.sameTypeRootTreeItem
.QueryInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
// Sync calls don't support cpow wrapping of returned results, so we
// send over a small container for the object we want.
let suitcase = {
_window: null,
setChromeWindow: function (aObj) { this._window = aObj; }
}
if (!winmm.sendSyncMessage("PDFJS:Parent:getChromeWindow", {},
{ suitcase: suitcase })[0]) {
Cu.reportError("A request for a CPOW wrapped chrome window " +
"failed for unknown reasons.");
return null;
}
return suitcase._window;
},
getFindBar: function (aWindow) {
let winmm = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.sameTypeRootTreeItem
.QueryInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
let suitcase = {
_findbar: null,
setFindBar: function (aObj) { this._findbar = aObj; }
}
if (!winmm.sendSyncMessage("PDFJS:Parent:getFindBar", {},
{ suitcase: suitcase })[0]) {
Cu.reportError("A request for a CPOW wrapped findbar " +
"failed for unknown reasons.");
return null;
}
return suitcase._findbar;
}
};

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2012 Mozilla Foundation
*
@ -22,8 +22,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
PDFJS.version = '1.0.712';
PDFJS.build = '6969ed4';
PDFJS.version = '1.0.801';
PDFJS.build = 'e77e5c4';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
@ -373,6 +373,7 @@ var PasswordException = (function PasswordExceptionClosure() {
return PasswordException;
})();
PDFJS.PasswordException = PasswordException;
var UnknownErrorException = (function UnknownErrorExceptionClosure() {
function UnknownErrorException(msg, details) {
@ -386,6 +387,7 @@ var UnknownErrorException = (function UnknownErrorExceptionClosure() {
return UnknownErrorException;
})();
PDFJS.UnknownErrorException = UnknownErrorException;
var InvalidPDFException = (function InvalidPDFExceptionClosure() {
function InvalidPDFException(msg) {
@ -398,6 +400,7 @@ var InvalidPDFException = (function InvalidPDFExceptionClosure() {
return InvalidPDFException;
})();
PDFJS.InvalidPDFException = InvalidPDFException;
var MissingPDFException = (function MissingPDFExceptionClosure() {
function MissingPDFException(msg) {
@ -410,6 +413,22 @@ var MissingPDFException = (function MissingPDFExceptionClosure() {
return MissingPDFException;
})();
PDFJS.MissingPDFException = MissingPDFException;
var UnexpectedResponseException =
(function UnexpectedResponseExceptionClosure() {
function UnexpectedResponseException(msg, status) {
this.name = 'UnexpectedResponseException';
this.message = msg;
this.status = status;
}
UnexpectedResponseException.prototype = new Error();
UnexpectedResponseException.constructor = UnexpectedResponseException;
return UnexpectedResponseException;
})();
PDFJS.UnexpectedResponseException = UnexpectedResponseException;
var NotImplementedException = (function NotImplementedExceptionClosure() {
function NotImplementedException(msg) {
@ -1448,6 +1467,11 @@ PDFJS.maxCanvasPixels = (PDFJS.maxCanvasPixels === undefined ?
* parameters: function that needs to be called with new password and reason
* (see {PasswordResponses}).
*
* @param {function} progressCallback is optional. It is used to be able to
* monitor the loading progress of the PDF file (necessary to implement e.g.
* a loading bar). The callback receives an {Object} with the properties:
* {number} loaded and {number} total.
*
* @return {Promise} A promise that is resolved with {@link PDFDocumentProxy}
* object.
*/
@ -2107,36 +2131,46 @@ var WorkerTransport = (function WorkerTransportClosure() {
this.workerReadyCapability.resolve(pdfDocument);
}, this);
messageHandler.on('NeedPassword', function transportPassword(data) {
messageHandler.on('NeedPassword',
function transportNeedPassword(exception) {
if (this.passwordCallback) {
return this.passwordCallback(updatePassword,
PasswordResponses.NEED_PASSWORD);
}
this.workerReadyCapability.reject(data.exception.message,
data.exception);
this.workerReadyCapability.reject(
new PasswordException(exception.message, exception.code));
}, this);
messageHandler.on('IncorrectPassword', function transportBadPass(data) {
messageHandler.on('IncorrectPassword',
function transportIncorrectPassword(exception) {
if (this.passwordCallback) {
return this.passwordCallback(updatePassword,
PasswordResponses.INCORRECT_PASSWORD);
}
this.workerReadyCapability.reject(data.exception.message,
data.exception);
this.workerReadyCapability.reject(
new PasswordException(exception.message, exception.code));
}, this);
messageHandler.on('InvalidPDF', function transportInvalidPDF(data) {
this.workerReadyCapability.reject(data.exception.name, data.exception);
messageHandler.on('InvalidPDF', function transportInvalidPDF(exception) {
this.workerReadyCapability.reject(
new InvalidPDFException(exception.message));
}, this);
messageHandler.on('MissingPDF', function transportMissingPDF(data) {
this.workerReadyCapability.reject(data.exception.message,
data.exception);
messageHandler.on('MissingPDF', function transportMissingPDF(exception) {
this.workerReadyCapability.reject(
new MissingPDFException(exception.message));
}, this);
messageHandler.on('UnknownError', function transportUnknownError(data) {
this.workerReadyCapability.reject(data.exception.message,
data.exception);
messageHandler.on('UnexpectedResponse',
function transportUnexpectedResponse(exception) {
this.workerReadyCapability.reject(
new UnexpectedResponseException(exception.message, exception.status));
}, this);
messageHandler.on('UnknownError',
function transportUnknownError(exception) {
this.workerReadyCapability.reject(
new UnknownErrorException(exception.message, exception.details));
}, this);
messageHandler.on('DataLoaded', function transportPage(data) {
@ -2232,10 +2266,6 @@ var WorkerTransport = (function WorkerTransportClosure() {
}
}, this);
messageHandler.on('DocError', function transportDocError(data) {
this.workerReadyCapability.reject(data);
}, this);
messageHandler.on('PageError', function transportError(data) {
var page = this.pageCache[data.pageNum - 1];
var intentState = page.intentStates[data.intent];

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2012 Mozilla Foundation
*
@ -22,8 +22,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
PDFJS.version = '1.0.712';
PDFJS.build = '6969ed4';
PDFJS.version = '1.0.801';
PDFJS.build = 'e77e5c4';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
@ -373,6 +373,7 @@ var PasswordException = (function PasswordExceptionClosure() {
return PasswordException;
})();
PDFJS.PasswordException = PasswordException;
var UnknownErrorException = (function UnknownErrorExceptionClosure() {
function UnknownErrorException(msg, details) {
@ -386,6 +387,7 @@ var UnknownErrorException = (function UnknownErrorExceptionClosure() {
return UnknownErrorException;
})();
PDFJS.UnknownErrorException = UnknownErrorException;
var InvalidPDFException = (function InvalidPDFExceptionClosure() {
function InvalidPDFException(msg) {
@ -398,6 +400,7 @@ var InvalidPDFException = (function InvalidPDFExceptionClosure() {
return InvalidPDFException;
})();
PDFJS.InvalidPDFException = InvalidPDFException;
var MissingPDFException = (function MissingPDFExceptionClosure() {
function MissingPDFException(msg) {
@ -410,6 +413,22 @@ var MissingPDFException = (function MissingPDFExceptionClosure() {
return MissingPDFException;
})();
PDFJS.MissingPDFException = MissingPDFException;
var UnexpectedResponseException =
(function UnexpectedResponseExceptionClosure() {
function UnexpectedResponseException(msg, status) {
this.name = 'UnexpectedResponseException';
this.message = msg;
this.status = status;
}
UnexpectedResponseException.prototype = new Error();
UnexpectedResponseException.constructor = UnexpectedResponseException;
return UnexpectedResponseException;
})();
PDFJS.UnexpectedResponseException = UnexpectedResponseException;
var NotImplementedException = (function NotImplementedExceptionClosure() {
function NotImplementedException(msg) {
@ -1455,6 +1474,12 @@ var ChunkedStream = (function ChunkedStreamClosure() {
return bytes.subarray(pos, end);
},
peekByte: function ChunkedStream_peekByte() {
var peekedByte = this.getByte();
this.pos--;
return peekedByte;
},
peekBytes: function ChunkedStream_peekBytes(length) {
var bytes = this.getBytes(length);
this.pos -= bytes.length;
@ -6863,20 +6888,21 @@ var CalRGBCS = (function CalRGBCSClosure() {
convertToRgb(this, src, srcOffset, dest, destOffset, 1);
},
getRgbBuffer: function CalRGBCS_getRgbBuffer(src, srcOffset, count,
dest, destOffset, bits) {
dest, destOffset, bits,
alpha01) {
var scale = 1 / ((1 << bits) - 1);
for (var i = 0; i < count; ++i) {
convertToRgb(this, src, srcOffset, dest, destOffset, scale);
srcOffset += 3;
destOffset += 3;
destOffset += 3 + alpha01;
}
},
getOutputLength: function CalRGBCS_getOutputLength(inputLength) {
return inputLength;
getOutputLength: function CalRGBCS_getOutputLength(inputLength, alpha01) {
return (inputLength * (3 + alpha01) / 3) | 0;
},
isPassthrough: ColorSpace.prototype.isPassthrough,
createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
fillRgb: ColorSpace.prototype.fillRgb,
isDefaultDecode: function CalRGBCS_isDefaultDecode(decodeMap) {
return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
},
@ -11106,9 +11132,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
// The Symbolic attribute can be misused for regular fonts
// Heuristic: we have to check if the font is a standard one also
if (!!(properties.flags & FontFlags.Symbolic)) {
encoding = (!properties.file && /Symbol/i.test(properties.name) ?
Encodings.SymbolSetEncoding :
Encodings.MacRomanEncoding);
encoding = Encodings.MacRomanEncoding;
if (!properties.file) {
if (/Symbol/i.test(properties.name)) {
encoding = Encodings.SymbolSetEncoding;
} else if (/Dingbats/i.test(properties.name)) {
encoding = Encodings.ZapfDingbatsEncoding;
}
}
}
properties.defaultEncoding = encoding;
}
@ -13613,7 +13644,7 @@ var Encodings = {
'parenrighttp', 'parenrightex', 'parenrightbt', 'bracketrighttp',
'bracketrightex', 'bracketrightbt', 'bracerighttp', 'bracerightmid',
'bracerightbt'],
zapfDingbatsEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '',
ZapfDingbatsEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
'space', 'a1', 'a2', 'a202', 'a3', 'a4', 'a5', 'a119', 'a118', 'a117',
'a11', 'a12', 'a13', 'a14', 'a15', 'a16', 'a105', 'a17', 'a18', 'a19',
@ -13624,19 +13655,19 @@ var Encodings = {
'a57', 'a58', 'a59', 'a60', 'a61', 'a62', 'a63', 'a64', 'a65', 'a66',
'a67', 'a68', 'a69', 'a70', 'a71', 'a72', 'a73', 'a74', 'a203', 'a75',
'a204', 'a76', 'a77', 'a78', 'a79', 'a81', 'a82', 'a83', 'a84', 'a97',
'a98', 'a99', 'a100', '', '', '', '', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
'', '', 'a101', 'a102', 'a103', 'a104', 'a106', 'a107', 'a108', 'a112',
'a111', 'a110', 'a109', 'a120', 'a121', 'a122', 'a123', 'a124', 'a125',
'a126', 'a127', 'a128', 'a129', 'a130', 'a131', 'a132', 'a133', 'a134',
'a135', 'a136', 'a137', 'a138', 'a139', 'a140', 'a141', 'a142', 'a143',
'a144', 'a145', 'a146', 'a147', 'a148', 'a149', 'a150', 'a151', 'a152',
'a153', 'a154', 'a155', 'a156', 'a157', 'a158', 'a159', 'a160', 'a161',
'a163', 'a164', 'a196', 'a165', 'a192', 'a166', 'a167', 'a168', 'a169',
'a170', 'a171', 'a172', 'a173', 'a162', 'a174', 'a175', 'a176', 'a177',
'a178', 'a179', 'a193', 'a180', 'a199', 'a181', 'a200', 'a182', '', 'a201',
'a183', 'a184', 'a197', 'a185', 'a194', 'a198', 'a186', 'a195', 'a187',
'a188', 'a189', 'a190', 'a191']
'a98', 'a99', 'a100', '', 'a89', 'a90', 'a93', 'a94', 'a91', 'a92', 'a205',
'a85', 'a206', 'a86', 'a87', 'a88', 'a95', 'a96', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '', '', '', '', 'a101', 'a102', 'a103',
'a104', 'a106', 'a107', 'a108', 'a112', 'a111', 'a110', 'a109', 'a120',
'a121', 'a122', 'a123', 'a124', 'a125', 'a126', 'a127', 'a128', 'a129',
'a130', 'a131', 'a132', 'a133', 'a134', 'a135', 'a136', 'a137', 'a138',
'a139', 'a140', 'a141', 'a142', 'a143', 'a144', 'a145', 'a146', 'a147',
'a148', 'a149', 'a150', 'a151', 'a152', 'a153', 'a154', 'a155', 'a156',
'a157', 'a158', 'a159', 'a160', 'a161', 'a163', 'a164', 'a196', 'a165',
'a192', 'a166', 'a167', 'a168', 'a169', 'a170', 'a171', 'a172', 'a173',
'a162', 'a174', 'a175', 'a176', 'a177', 'a178', 'a179', 'a193', 'a180',
'a199', 'a181', 'a200', 'a182', '', 'a201', 'a183', 'a184', 'a197', 'a185',
'a194', 'a198', 'a186', 'a195', 'a187', 'a188', 'a189', 'a190', 'a191']
};
/**
@ -13806,8 +13837,11 @@ var GlyphMapForStandardFonts = {
'156': 8747, '157': 170, '158': 186, '159': 8486, '160': 230, '161': 248,
'162': 191, '163': 161, '164': 172, '165': 8730, '166': 402, '167': 8776,
'168': 8710, '169': 171, '170': 187, '171': 8230, '210': 218, '223': 711,
'227': 353, '229': 382, '234': 253, '253': 268, '254': 269, '258': 258,
'268': 283, '269': 313, '278': 328, '284': 345, '292': 367, '305': 963,
'224': 321, '225': 322, '227': 353, '229': 382, '234': 253, '252': 263,
'253': 268, '254': 269, '258': 258, '260': 260, '261': 261, '265': 280,
'266': 281, '268': 283, '269': 313, '275': 323, '276': 324, '278': 328,
'284': 345, '285': 346, '286': 347, '292': 367, '295': 377, '296': 378,
'298': 380, '305': 963,
'306': 964, '307': 966, '308': 8215, '309': 8252, '310': 8319, '311': 8359,
'312': 8592, '313': 8593, '337': 9552, '493': 1039, '494': 1040, '705': 1524,
'706': 8362, '710': 64288, '711': 64298, '759': 1617, '761': 1776,
@ -13848,29 +13882,42 @@ var GlyphMapForStandardFonts = {
'3316': 578, '3379': 42785, '3393': 1159, '3416': 8377
};
// Some characters, e.g. copyrightserif, mapped to the private use area and
// Some characters, e.g. copyrightserif, are mapped to the private use area and
// might not be displayed using standard fonts. Mapping/hacking well-known chars
// to the similar equivalents in the normal characters range.
var SpecialPUASymbols = {
'63721': 0x00A9, // copyrightsans (0xF8E9) => copyright
'63193': 0x00A9, // copyrightserif (0xF6D9) => copyright
'63720': 0x00AE, // registersans (0xF8E8) => registered
'63194': 0x00AE, // registerserif (0xF6DA) => registered
'63722': 0x2122, // trademarksans (0xF8EA) => trademark
'63195': 0x2122, // trademarkserif (0xF6DB) => trademark
'63729': 0x23A7, // bracelefttp (0xF8F1)
'63730': 0x23A8, // braceleftmid (0xF8F2)
'63731': 0x23A9, // braceleftbt (0xF8F3)
'63740': 0x23AB, // bracerighttp (0xF8FC)
'63741': 0x23AC, // bracerightmid (0xF8FD)
'63742': 0x23AD, // bracerightmid (0xF8FE)
'63726': 0x23A1, // bracketlefttp (0xF8EE)
'63727': 0x23A2, // bracketleftex (0xF8EF)
'63728': 0x23A3, // bracketleftbt (0xF8F0)
'63737': 0x23A4, // bracketrighttp (0xF8F9)
'63738': 0x23A5, // bracketrightex (0xF8FA)
'63739': 0x23A6, // bracketrightbt (0xF8FB)
'63723': 0x239B, // parenlefttp (0xF8EB)
'63724': 0x239C, // parenleftex (0xF8EC)
'63725': 0x239D, // parenleftbt (0xF8ED)
'63734': 0x239E, // parenrighttp (0xF8F6)
'63735': 0x239F, // parenrightex (0xF8F7)
'63736': 0x23A0, // parenrightbt (0xF8F8)
};
function mapSpecialUnicodeValues(code) {
if (code >= 0xFFF0 && code <= 0xFFFF) { // Specials unicode block.
return 0;
} else if (code >= 0xF600 && code <= 0xF8FF) {
return (SpecialPUASymbols[code] || code);
}
switch (code) {
case 0xF8E9: // copyrightsans
case 0xF6D9: // copyrightserif
return 0x00A9; // copyright
case 0xF8E8: // registersans
case 0xF6DA: // registerserif
return 0x00AE; // registered
case 0xF8EA: // trademarksans
case 0xF6DB: // trademarkserif
return 0x2122; // trademark
default:
return code;
}
return code;
}
var UnicodeRanges = [
@ -15725,7 +15772,7 @@ var OpenTypeFileBuilder = (function OpenTypeFileBuilderClosure() {
*/
var Font = (function FontClosure() {
function Font(name, file, properties) {
var charCode, glyphName;
var charCode, glyphName, fontChar;
this.name = name;
this.loadedName = properties.loadedName;
@ -15815,7 +15862,23 @@ var Font = (function FontClosure() {
} else if (/Symbol/i.test(fontName)) {
var symbols = Encodings.SymbolSetEncoding;
for (charCode in symbols) {
var fontChar = GlyphsUnicode[symbols[charCode]];
fontChar = GlyphsUnicode[symbols[charCode]];
if (!fontChar) {
continue;
}
this.toFontChar[charCode] = fontChar;
}
} else if (/Dingbats/i.test(fontName)) {
var dingbats = Encodings.ZapfDingbatsEncoding;
for (charCode in dingbats) {
fontChar = DingbatsGlyphsUnicode[dingbats[charCode]];
if (!fontChar) {
continue;
}
this.toFontChar[charCode] = fontChar;
}
for (charCode in properties.differences) {
fontChar = DingbatsGlyphsUnicode[properties.differences[charCode]];
if (!fontChar) {
continue;
}
@ -16648,16 +16711,12 @@ var Font = (function FontClosure() {
var numMissing = numOfSidebearings -
((metrics.length - numOfMetrics * 4) >> 1);
var i, ii;
if (numMissing > 0) {
font.pos = (font.start ? font.start : 0) + metrics.offset;
var entries = '';
for (i = 0, ii = metrics.length; i < ii; i++) {
entries += String.fromCharCode(font.getByte());
}
for (i = 0; i < numMissing; i++) {
entries += '\x00\x00';
}
// For each missing glyph, we set both the width and lsb to 0 (zero).
// Since we need to add two properties for each glyph, this explains
// the use of |numMissing * 2| when initializing the typed array.
var entries = new Uint8Array(metrics.length + numMissing * 2);
entries.set(metrics.data);
metrics.data = entries;
}
}
@ -17389,7 +17448,15 @@ var Font = (function FontClosure() {
// where the the font is symbolic and it has an encoding.
if (hasEncoding &&
(cmapPlatformId === 3 && cmapEncodingId === 1 ||
cmapPlatformId === 1 && cmapEncodingId === 0)) {
cmapPlatformId === 1 && cmapEncodingId === 0) ||
(cmapPlatformId === -1 && cmapEncodingId === -1 && // Temporary hack
!!Encodings[properties.baseEncodingName])) { // Temporary hack
// When no preferred cmap table was found and |baseEncodingName| is
// one of the predefined encodings, we seem to obtain a better
// |charCodeToGlyphId| map from the code below (fixes bug 1057544).
// TODO: Note that this is a hack which should be removed as soon as
// we have proper support for more exotic cmap tables.
var baseEncoding = [];
if (properties.baseEncodingName === 'MacRomanEncoding' ||
properties.baseEncodingName === 'WinAnsiEncoding') {
@ -25399,6 +25466,211 @@ var GlyphsUnicode = {
'.notdef': 0x0000
};
var DingbatsGlyphsUnicode = {
space: 0x0020,
a1: 0x2701,
a2: 0x2702,
a202: 0x2703,
a3: 0x2704,
a4: 0x260E,
a5: 0x2706,
a119: 0x2707,
a118: 0x2708,
a117: 0x2709,
a11: 0x261B,
a12: 0x261E,
a13: 0x270C,
a14: 0x270D,
a15: 0x270E,
a16: 0x270F,
a105: 0x2710,
a17: 0x2711,
a18: 0x2712,
a19: 0x2713,
a20: 0x2714,
a21: 0x2715,
a22: 0x2716,
a23: 0x2717,
a24: 0x2718,
a25: 0x2719,
a26: 0x271A,
a27: 0x271B,
a28: 0x271C,
a6: 0x271D,
a7: 0x271E,
a8: 0x271F,
a9: 0x2720,
a10: 0x2721,
a29: 0x2722,
a30: 0x2723,
a31: 0x2724,
a32: 0x2725,
a33: 0x2726,
a34: 0x2727,
a35: 0x2605,
a36: 0x2729,
a37: 0x272A,
a38: 0x272B,
a39: 0x272C,
a40: 0x272D,
a41: 0x272E,
a42: 0x272F,
a43: 0x2730,
a44: 0x2731,
a45: 0x2732,
a46: 0x2733,
a47: 0x2734,
a48: 0x2735,
a49: 0x2736,
a50: 0x2737,
a51: 0x2738,
a52: 0x2739,
a53: 0x273A,
a54: 0x273B,
a55: 0x273C,
a56: 0x273D,
a57: 0x273E,
a58: 0x273F,
a59: 0x2740,
a60: 0x2741,
a61: 0x2742,
a62: 0x2743,
a63: 0x2744,
a64: 0x2745,
a65: 0x2746,
a66: 0x2747,
a67: 0x2748,
a68: 0x2749,
a69: 0x274A,
a70: 0x274B,
a71: 0x25CF,
a72: 0x274D,
a73: 0x25A0,
a74: 0x274F,
a203: 0x2750,
a75: 0x2751,
a204: 0x2752,
a76: 0x25B2,
a77: 0x25BC,
a78: 0x25C6,
a79: 0x2756,
a81: 0x25D7,
a82: 0x2758,
a83: 0x2759,
a84: 0x275A,
a97: 0x275B,
a98: 0x275C,
a99: 0x275D,
a100: 0x275E,
a101: 0x2761,
a102: 0x2762,
a103: 0x2763,
a104: 0x2764,
a106: 0x2765,
a107: 0x2766,
a108: 0x2767,
a112: 0x2663,
a111: 0x2666,
a110: 0x2665,
a109: 0x2660,
a120: 0x2460,
a121: 0x2461,
a122: 0x2462,
a123: 0x2463,
a124: 0x2464,
a125: 0x2465,
a126: 0x2466,
a127: 0x2467,
a128: 0x2468,
a129: 0x2469,
a130: 0x2776,
a131: 0x2777,
a132: 0x2778,
a133: 0x2779,
a134: 0x277A,
a135: 0x277B,
a136: 0x277C,
a137: 0x277D,
a138: 0x277E,
a139: 0x277F,
a140: 0x2780,
a141: 0x2781,
a142: 0x2782,
a143: 0x2783,
a144: 0x2784,
a145: 0x2785,
a146: 0x2786,
a147: 0x2787,
a148: 0x2788,
a149: 0x2789,
a150: 0x278A,
a151: 0x278B,
a152: 0x278C,
a153: 0x278D,
a154: 0x278E,
a155: 0x278F,
a156: 0x2790,
a157: 0x2791,
a158: 0x2792,
a159: 0x2793,
a160: 0x2794,
a161: 0x2192,
a163: 0x2194,
a164: 0x2195,
a196: 0x2798,
a165: 0x2799,
a192: 0x279A,
a166: 0x279B,
a167: 0x279C,
a168: 0x279D,
a169: 0x279E,
a170: 0x279F,
a171: 0x27A0,
a172: 0x27A1,
a173: 0x27A2,
a162: 0x27A3,
a174: 0x27A4,
a175: 0x27A5,
a176: 0x27A6,
a177: 0x27A7,
a178: 0x27A8,
a179: 0x27A9,
a193: 0x27AA,
a180: 0x27AB,
a199: 0x27AC,
a181: 0x27AD,
a200: 0x27AE,
a182: 0x27AF,
a201: 0x27B1,
a183: 0x27B2,
a184: 0x27B3,
a197: 0x27B4,
a185: 0x27B5,
a194: 0x27B6,
a198: 0x27B7,
a186: 0x27B8,
a195: 0x27B9,
a187: 0x27BA,
a188: 0x27BB,
a189: 0x27BC,
a190: 0x27BD,
a191: 0x27BE,
a89: 0x2768, // 0xF8D7
a90: 0x2769, // 0xF8D8
a93: 0x276A, // 0xF8D9
a94: 0x276B, // 0xF8DA
a91: 0x276C, // 0xF8DB
a92: 0x276D, // 0xF8DC
a205: 0x276E, // 0xF8DD
a85: 0x276F, // 0xF8DE
a206: 0x2770, // 0xF8DF
a86: 0x2771, // 0xF8E0
a87: 0x2772, // 0xF8E1
a88: 0x2773, // 0xF8E2
a95: 0x2774, // 0xF8E3
a96: 0x2775, // 0xF8E4
'.notdef': 0x0000
};
var PDFImage = (function PDFImageClosure() {
@ -29318,6 +29590,9 @@ var Parser = (function ParserClosure() {
return new NullStream(stream);
}
try {
if (params) {
params = this.fetchIfRef(params);
}
var xrefStreamStats = this.xref.stats.streamTypes;
if (name === 'FlateDecode' || name === 'Fl') {
xrefStreamStats[StreamType.FLATE] = true;
@ -29341,6 +29616,22 @@ var Parser = (function ParserClosure() {
return new LZWStream(stream, maybeLength, earlyChange);
}
if (name === 'DCTDecode' || name === 'DCT') {
// According to the specification: for inline images, the ID operator
// shall be followed by a single whitespace character (unless it uses
// ASCII85Decode or ASCIIHexDecode filters).
// In practice this only seems to be followed for inline JPEG images,
// and generally ignoring the first byte of the stream if it is a
// whitespace char can even *cause* issues (e.g. in the CCITTFaxDecode
// filters used in issue2984.pdf).
// Hence when the first byte of the stream of an inline JPEG image is
// a whitespace character, we thus simply skip over it.
if (isCmd(this.buf1, 'ID')) {
var firstByte = stream.peekByte();
if (firstByte === 0x0A /* LF */ || firstByte === 0x0D /* CR */ ||
firstByte === 0x20 /* SPACE */) {
stream.skip();
}
}
xrefStreamStats[StreamType.DCT] = true;
return new JpegStream(stream, maybeLength, stream.dict, this.xref);
}
@ -29447,7 +29738,7 @@ var Lexer = (function LexerClosure() {
return (this.currentChar = this.stream.getByte());
},
peekChar: function Lexer_peekChar() {
return this.stream.peekBytes(1)[0];
return this.stream.peekByte();
},
getNumber: function Lexer_getNumber() {
var ch = this.currentChar;
@ -30104,6 +30395,11 @@ var Stream = (function StreamClosure() {
this.pos = end;
return bytes.subarray(pos, end);
},
peekByte: function Stream_peekByte() {
var peekedByte = this.getByte();
this.pos--;
return peekedByte;
},
peekBytes: function Stream_peekBytes(length) {
var bytes = this.getBytes(length);
this.pos -= bytes.length;
@ -30233,6 +30529,11 @@ var DecodeStream = (function DecodeStreamClosure() {
this.pos = end;
return this.buffer.subarray(pos, end);
},
peekByte: function DecodeStream_peekByte() {
var peekedByte = this.getByte();
this.pos--;
return peekedByte;
},
peekBytes: function DecodeStream_peekBytes(length) {
var bytes = this.getBytes(length);
this.pos -= bytes.length;
@ -30558,7 +30859,7 @@ var FlateStream = (function FlateStreamClosure() {
var end = bufferLength + blockLen;
this.bufferLength = end;
if (blockLen === 0) {
if (str.peekBytes(1).length === 0) {
if (str.peekByte() === -1) {
this.eof = true;
}
} else {
@ -31064,7 +31365,8 @@ var Jbig2Stream = (function Jbig2StreamClosure() {
var jbig2Image = new Jbig2Image();
var chunks = [], decodeParams = this.dict.get('DecodeParms');
var chunks = [], xref = this.dict.xref;
var decodeParams = xref.fetchIfRef(this.dict.get('DecodeParms'));
// According to the PDF specification, DecodeParms can be either
// a dictionary, or an array whose elements are dictionaries.
@ -31073,7 +31375,7 @@ var Jbig2Stream = (function Jbig2StreamClosure() {
warn('JBIG2 - \'DecodeParms\' array with multiple elements ' +
'not supported.');
}
decodeParams = decodeParams[0];
decodeParams = xref.fetchIfRef(decodeParams[0]);
}
if (decodeParams && decodeParams.has('JBIG2Globals')) {
var globalsStream = decodeParams.get('JBIG2Globals');
@ -32593,14 +32895,16 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
},
onError: function onError(status) {
var exception;
if (status === 404) {
var exception = new MissingPDFException('Missing PDF "' +
source.url + '".');
handler.send('MissingPDF', { exception: exception });
exception = new MissingPDFException('Missing PDF "' +
source.url + '".');
handler.send('MissingPDF', exception);
} else {
handler.send('DocError', 'Unexpected server response (' +
status + ') while retrieving PDF "' +
source.url + '".');
exception = new UnexpectedResponseException(
'Unexpected server response (' + status +
') while retrieving PDF "' + source.url + '".', status);
handler.send('UnexpectedResponse', exception);
}
},
@ -32652,26 +32956,19 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
var onFailure = function(e) {
if (e instanceof PasswordException) {
if (e.code === PasswordResponses.NEED_PASSWORD) {
handler.send('NeedPassword', {
exception: e
});
handler.send('NeedPassword', e);
} else if (e.code === PasswordResponses.INCORRECT_PASSWORD) {
handler.send('IncorrectPassword', {
exception: e
});
handler.send('IncorrectPassword', e);
}
} else if (e instanceof InvalidPDFException) {
handler.send('InvalidPDF', {
exception: e
});
handler.send('InvalidPDF', e);
} else if (e instanceof MissingPDFException) {
handler.send('MissingPDF', {
exception: e
});
handler.send('MissingPDF', e);
} else if (e instanceof UnexpectedResponseException) {
handler.send('UnexpectedResponse', e);
} else {
handler.send('UnknownError', {
exception: new UnknownErrorException(e.message, e.toString())
});
handler.send('UnknownError',
new UnknownErrorException(e.message, e.toString()));
}
};
@ -34605,7 +34902,7 @@ var JpxImage = (function JpxImageClosure() {
codeblockWidth: xcb_,
codeblockHeight: ycb_,
numcodeblockwide: cbx1 - cbx0 + 1,
numcodeblockhigh: cby1 - cby1 + 1
numcodeblockhigh: cby1 - cby0 + 1
};
subband.codeblocks = codeblocks;
subband.precincts = precincts;

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2012 Mozilla Foundation
*

Просмотреть файл

@ -0,0 +1,35 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2014 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* jshint esnext:true */
/* globals Components, PdfjsContentUtils, PdfJs */
'use strict';
/*
* pdfjschildbootstrap.js loads into the content process to take care of
* initializing our built-in version of pdfjs when running remote.
*/
Components.utils.import('resource://pdf.js/PdfJs.jsm');
Components.utils.import('resource://pdf.js/PdfjsContentUtils.jsm');
// init content utils shim pdfjs will use to access privileged apis.
PdfjsContentUtils.init();
// register various pdfjs factories that hook us into content loading.
PdfJs.updateRegistration();

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2012 Mozilla Foundation
*

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* globals FirefoxCom */

Просмотреть файл

@ -345,6 +345,9 @@ html[dir='rtl'] .findbar {
background-repeat: no-repeat;
background-position: right;
}
html[dir='rtl'] #findInput[data-status="pending"] {
background-position: left;
}
.secondaryToolbar {
padding: 6px;
@ -940,7 +943,7 @@ html[dir='rtl'] .verticalToolbarSeparator {
}
.horizontalToolbarSeparator {
display: block;
display: block;
margin: 0 0 4px 0;
height: 1px;
width: 100%;
@ -1208,8 +1211,6 @@ canvas {
top: 0;
right: 0;
bottom: 0;
color: #000;
font-family: sans-serif;
overflow: hidden;
}
@ -1218,6 +1219,8 @@ canvas {
position: absolute;
white-space: pre;
cursor: text;
-moz-transform-origin: 0% 0%;
transform-origin: 0% 0%;
}
.textLayer .highlight {
@ -1386,7 +1389,7 @@ canvas {
}
.dialog .separator {
display: block;
display: block;
margin: 4px 0 4px 0;
height: 1px;
width: 100%;
@ -1562,7 +1565,7 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * {
background: url(images/toolbarButton-menuArrows@2x.png) no-repeat;
background-size: 7px 16px;
}
html[dir='ltr'] .toolbarButton#sidebarToggle::before {
content: url(images/toolbarButton-sidebarToggle@2x.png);
}
@ -1852,4 +1855,3 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * {
display: none;
}
}

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2012 Mozilla Foundation
*
@ -2034,6 +2034,11 @@ var GrabToPan = (function GrabToPanClosure() {
event.preventDefault();
event.stopPropagation();
this.document.documentElement.classList.add(this.CSS_CLASS_GRABBING);
var focusedElement = document.activeElement;
if (focusedElement && !focusedElement.contains(event.target)) {
focusedElement.blur();
}
},
/**
@ -2527,7 +2532,7 @@ var DocumentProperties = {
minutes += offsetMinutes;
} else if (utRel === '+') {
hours -= offsetHours;
minutes += offsetMinutes;
minutes -= offsetMinutes;
}
// Return the new date format from the user's locale.
@ -2795,7 +2800,9 @@ var PDFView = {
scale = Math.min(pageWidthScale, pageHeightScale);
break;
case 'auto':
scale = Math.min(MAX_AUTO_SCALE, pageWidthScale);
var isLandscape = (currentPage.width > currentPage.height);
var horizontalScale = isLandscape ? pageHeightScale : pageWidthScale;
scale = Math.min(MAX_AUTO_SCALE, horizontalScale);
break;
default:
console.error('pdfViewSetScale: \'' + value +
@ -3053,7 +3060,7 @@ var PDFView = {
},
// TODO(mack): This function signature should really be pdfViewOpen(url, args)
open: function pdfViewOpen(url, scale, password,
open: function pdfViewOpen(file, scale, password,
pdfDataRangeTransport, args) {
if (this.pdfDocument) {
// Reload the preferences if a document was previously opened.
@ -3062,11 +3069,14 @@ var PDFView = {
this.close();
var parameters = {password: password};
if (typeof url === 'string') { // URL
this.setTitleUsingUrl(url);
parameters.url = url;
} else if (url && 'byteLength' in url) { // ArrayBuffer
parameters.data = url;
if (typeof file === 'string') { // URL
this.setTitleUsingUrl(file);
parameters.url = file;
} else if (file && 'byteLength' in file) { // ArrayBuffer
parameters.data = file;
} else if (file.url && file.originalUrl) {
this.setTitleUsingUrl(file.originalUrl);
parameters.url = file.url;
}
if (args) {
for (var prop in args) {
@ -3094,21 +3104,22 @@ var PDFView = {
self.load(pdfDocument, scale);
self.loading = false;
},
function getDocumentError(message, exception) {
function getDocumentError(exception) {
var message = exception && exception.message;
var loadingErrorMessage = mozL10n.get('loading_error', null,
'An error occurred while loading the PDF.');
if (exception && exception.name === 'InvalidPDFException') {
if (exception instanceof PDFJS.InvalidPDFException) {
// change error message also for other builds
loadingErrorMessage = mozL10n.get('invalid_file_error', null,
'Invalid or corrupted PDF file.');
}
if (exception && exception.name === 'MissingPDFException') {
'Invalid or corrupted PDF file.');
} else if (exception instanceof PDFJS.MissingPDFException) {
// special message for missing PDF's
loadingErrorMessage = mozL10n.get('missing_file_error', null,
'Missing PDF file.');
'Missing PDF file.');
} else if (exception instanceof PDFJS.UnexpectedResponseException) {
loadingErrorMessage = mozL10n.get('unexpected_response_error', null,
'Unexpected server response.');
}
var moreInfo = {
@ -3528,7 +3539,11 @@ var PDFView = {
var pdfTitle;
if (metadata && metadata.has('dc:title')) {
pdfTitle = metadata.get('dc:title');
var title = metadata.get('dc:title');
// Ghostscript sometimes return 'Untitled', sets the title to 'Untitled'
if (title !== 'Untitled') {
pdfTitle = title;
}
}
if (!pdfTitle && info && info['Title']) {
@ -3575,7 +3590,7 @@ var PDFView = {
setInitialView: function pdfViewSetInitialView(storedHash, scale) {
// Reset the current scale, as otherwise the page's scale might not get
// updated if the zoom level stayed the same.
this.currentScale = 0;
this.currentScale = UNKNOWN_SCALE;
this.currentScaleValue = null;
// When opening a new file (when one is already loaded in the viewer):
// Reset 'currentPageNumber', since otherwise the page's scale will be wrong
@ -5074,15 +5089,21 @@ var TextLayerBuilder = (function TextLayerBuilderClosure() {
var width = ctx.measureText(textDiv.textContent).width;
if (width > 0) {
textLayerFrag.appendChild(textDiv);
// Dataset values come of type string.
var textScale = textDiv.dataset.canvasWidth / width;
var transform;
if (textDiv.dataset.canvasWidth !== undefined) {
// Dataset values come of type string.
var textScale = textDiv.dataset.canvasWidth / width;
transform = 'scaleX(' + textScale + ')';
} else {
transform = '';
}
var rotation = textDiv.dataset.angle;
var transform = 'scale(' + textScale + ', 1)';
if (rotation) {
transform = 'rotate(' + rotation + 'deg) ' + transform;
}
CustomStyle.setProp('transform' , textDiv, transform);
CustomStyle.setProp('transformOrigin' , textDiv, '0% 0%');
if (transform) {
CustomStyle.setProp('transform' , textDiv, transform);
}
}
}
@ -5157,10 +5178,15 @@ var TextLayerBuilder = (function TextLayerBuilderClosure() {
if (angle !== 0) {
textDiv.dataset.angle = angle * (180 / Math.PI);
}
if (style.vertical) {
textDiv.dataset.canvasWidth = geom.height * this.viewport.scale;
} else {
textDiv.dataset.canvasWidth = geom.width * this.viewport.scale;
// We don't bother scaling single-char text divs, because it has very
// little effect on text highlighting. This makes scrolling on docs with
// lots of such divs a lot faster.
if (textDiv.textContent.length > 1) {
if (style.vertical) {
textDiv.dataset.canvasWidth = geom.height * this.viewport.scale;
} else {
textDiv.dataset.canvasWidth = geom.width * this.viewport.scale;
}
}
},
@ -5768,9 +5794,12 @@ window.addEventListener('localized', function localized(evt) {
PDFView.animationStartedPromise.then(function() {
// Adjust the width of the zoom box to fit the content.
// Note: This is only done if the zoom box is actually visible,
// since otherwise element.clientWidth will return 0.
// Note: If the window is narrow enough that the zoom box is not visible,
// we temporarily show it to be able to adjust its width.
var container = document.getElementById('scaleSelectContainer');
if (container.clientWidth === 0) {
container.setAttribute('style', 'display: inherit;');
}
if (container.clientWidth > 0) {
var select = document.getElementById('scaleSelect');
select.setAttribute('style', 'min-width: inherit;');

Просмотреть файл

@ -75,21 +75,15 @@ OrganizerQueryDownloads=Downloads
OrganizerQueryAllBookmarks=All Bookmarks
OrganizerQueryTags=Tags
# LOCALIZATION NOTE (tagResultLabel) :
# LOCALIZATION NOTE (tagResultLabel, bookmarkResultLabel, switchtabResultLabel,
# keywordResultLabel)
# Noun used to describe the location bar autocomplete result type
# to users with screen readers
# See createResultLabel() in urlbarBindings.xml
tagResultLabel=Tag
# LOCALIZATION NOTE (bookmarkResultLabel) :
# Noun used to describe the location bar autocomplete result type
# to users with screen readers
# See createResultLabel() in urlbarBindings.xml
bookmarkResultLabel=Bookmark
# LOCALIZATION NOTE (switchtabResultLabel) :
# Noun used to describe the location bar autocomplete result type
# to users with screen readers
# See createResultLabel() in urlbarBindings.xml
switchtabResultLabel=Tab
keywordResultLabel=Keyword
# LOCALIZATION NOTE (lockPrompt.text)
# %S will be replaced with the application name.

Просмотреть файл

@ -146,6 +146,7 @@ loading_error_indicator=Error
loading_error=An error occurred while loading the PDF.
invalid_file_error=Invalid or corrupted PDF file.
missing_file_error=Missing PDF file.
unexpected_response_error=Unexpected server response.
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
# "{{type}}" will be replaced with an annotation type from a list defined in

Просмотреть файл

@ -134,19 +134,6 @@
background-size: auto;
}
/* Use a pseudo-element to overlay a gradient on the thumbnail */
.newtab-site[type=history]:not(:hover) .newtab-thumbnail:first-child::after {
background-image: linear-gradient(0deg, rgba(251, 251, 251, 0.8), rgba(251, 251, 251, 0) 33%);
border-radius: inherit;
bottom: 0;
content: "";
left: 0;
pointer-events: none;
position: absolute;
right: 0;
top: 0;
}
/* TITLES */
.newtab-title {
color: #737373;

Просмотреть файл

@ -4,9 +4,6 @@
package org.mozilla.gecko.annotationProcessors.classloader;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
/**
@ -46,37 +43,9 @@ public class JarClassIterator implements Iterator<ClassWithOptions> {
if (canonicalName == null || "null".equals(canonicalName)) {
// Anonymous inner class - unsupported.
return next();
} else {
String generateName = null;
for (Annotation annotation : ret.getAnnotations()) {
Class<?> annotationType = annotation.annotationType();
if (annotationType.getCanonicalName().equals("org.mozilla.gecko.mozglue.generatorannotations.GeneratorOptions")) {
try {
// Determine the explicitly-given name of the stub to generate, if any.
final Method generateNameMethod = annotationType.getDeclaredMethod("generatedClassName");
generateNameMethod.setAccessible(true);
generateName = (String) generateNameMethod.invoke(annotation);
break;
} catch (NoSuchMethodException e) {
System.err.println("Unable to find expected field on GeneratorOptions annotation. Did the signature change?");
e.printStackTrace(System.err);
System.exit(3);
} catch (IllegalAccessException e) {
System.err.println("IllegalAccessException reading fields on GeneratorOptions annotation. Seems the semantics of Reflection have changed...");
e.printStackTrace(System.err);
System.exit(4);
} catch (InvocationTargetException e) {
System.err.println("InvocationTargetException reading fields on GeneratorOptions annotation. This really shouldn't happen.");
e.printStackTrace(System.err);
System.exit(5);
}
}
}
if (generateName == null) {
generateName = ret.getSimpleName();
}
return new ClassWithOptions(ret, generateName);
}
return new ClassWithOptions(ret, ret.getSimpleName());
} catch (ClassNotFoundException e) {
System.err.println("Unable to enumerate class: " + className + ". Corrupted jar file?");
e.printStackTrace();

Просмотреть файл

@ -14,6 +14,22 @@ DEBUG_JARSIGNER=$(PYTHON) $(abspath $(topsrcdir)/mobile/android/debug_sign_tool.
--jarsigner=$(JARSIGNER) \
$(NULL)
# RELEASE_JARSIGNER release signs if possible.
ifdef MOZ_SIGN_CMD
RELEASE_JARSIGNER := $(MOZ_SIGN_CMD) -f jar
else
RELEASE_JARSIGNER := $(DEBUG_JARSIGNER)
endif
# $(1) is the full path to input: foo-debug-unsigned-unaligned.apk.
# $(2) is the full path to output: foo.apk.
# Use this like: $(call RELEASE_SIGN_ANDROID_APK,foo-debug-unsigned-unaligned.apk,foo.apk)
RELEASE_SIGN_ANDROID_APK = \
cp $(1) $(2)-unaligned.apk && \
$(RELEASE_JARSIGNER) $(2)-unaligned.apk && \
$(ZIPALIGN) -f -v 4 $(2)-unaligned.apk $(2) && \
$(RM) $(2)-unaligned.apk
# For Android, this defaults to $(ANDROID_SDK)/android.jar
ifndef JAVA_BOOTCLASSPATH
JAVA_BOOTCLASSPATH = $(ANDROID_SDK)/android.jar

Просмотреть файл

@ -0,0 +1,148 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/* global Components, Services, dump */
"use strict";
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
this.EXPORTED_SYMBOLS = ["TrustedHostedAppsUtils"];
Cu.import("resource://gre/modules/Services.jsm");
#ifdef MOZ_WIDGET_ANDROID
// On Android, define the "debug" function as a binding of the "d" function
// from the AndroidLog module so it gets the "debug" priority and a log tag.
// We always report debug messages on Android because it's unnecessary
// to restrict reporting, per bug 1003469.
let debug = Cu
.import("resource://gre/modules/AndroidLog.jsm", {})
.AndroidLog.d.bind(null, "TrustedHostedAppsUtils");
#else
// Elsewhere, report debug messages only if dom.mozApps.debug is set to true.
// The pref is only checked once, on startup, so restart after changing it.
let debug = Services.prefs.getBoolPref("dom.mozApps.debug") ?
aMsg => dump("-*- TrustedHostedAppsUtils.jsm : " + aMsg + "\n") :
() => {};
#endif
/**
* Verification functions for Trusted Hosted Apps.
* (Manifest signature verification is in Webapps.jsm as part of
* regular signature verification.)
*/
this.TrustedHostedAppsUtils = {
/**
* Check if the given host is pinned in the CA pinning database.
*/
isHostPinned: function (aUrl) {
let uri;
try {
uri = Services.io.newURI(aUrl, null, null);
} catch(e) {
debug("Host parsing failed: " + e);
return false;
}
// TODO: use nsSiteSecurityService.isSecureURI()
if (!uri.host || "https" != uri.scheme) {
return false;
}
// Check certificate pinning
let siteSecurityService;
try {
siteSecurityService = Cc["@mozilla.org/ssservice;1"]
.getService(Ci.nsISiteSecurityService);
} catch (e) {
debug("nsISiteSecurityService error: " + e);
// unrecoverable error, don't bug the user
throw "CERTDB_ERROR";
}
if (siteSecurityService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HPKP, uri.host, 0)) {
debug("\tvalid certificate pinning for host: " + uri.host + "\n");
return true;
}
debug("\tHost NOT pinned: " + uri.host + "\n");
return false;
},
/**
* Take a CSP policy string as input and ensure that it contains at
* least the directives that are required ('script-src' and
* 'style-src'). If the CSP policy string is 'undefined' or does
* not contain some of the required csp directives the function will
* return empty list with status set to false. Otherwise a parsed
* list of the unique sources listed from the required csp
* directives is returned.
*/
getCSPWhiteList: function(aCsp) {
let isValid = false;
let whiteList = [];
let requiredDirectives = [ "script-src", "style-src" ];
if (aCsp) {
let validDirectives = [];
let directives = aCsp.split(";");
// TODO: Use nsIContentSecurityPolicy
directives
.map(aDirective => aDirective.trim().split(" "))
.filter(aList => aList.length > 1)
// we only restrict on requiredDirectives
.filter(aList => (requiredDirectives.indexOf(aList[0]) != -1))
.forEach(aList => {
// aList[0] contains the directive name.
// aList[1..n] contains sources.
let directiveName = aList.shift()
let sources = aList;
if ((-1 == validDirectives.indexOf(directiveName))) {
validDirectives.push(directiveName);
}
whiteList.push(...sources.filter(
// 'self' is checked separately during manifest check
aSource => (aSource !="'self'" && whiteList.indexOf(aSource) == -1)
));
});
// Check if all required directives are present.
isValid = requiredDirectives.length === validDirectives.length;
if (!isValid) {
debug("White list doesn't contain all required directives!");
whiteList = [];
}
}
debug("White list contains " + whiteList.length + " hosts");
return { list: whiteList, valid: isValid };
},
/**
* Verify that the given csp is valid:
* 1. contains required directives "script-src" and "style-src"
* 2. required directives contain only "https" URLs
* 3. domains of the restricted sources exist in the CA pinning database
*/
verifyCSPWhiteList: function(aCsp) {
let domainWhitelist = this.getCSPWhiteList(aCsp);
if (!domainWhitelist.valid) {
debug("TRUSTED_APPLICATION_WHITELIST_PARSING_FAILED");
return false;
}
if (!domainWhitelist.list.every(aUrl => this.isHostPinned(aUrl))) {
debug("TRUSTED_APPLICATION_WHITELIST_VALIDATION_FAILED");
return false;
}
return true;
}
};

Просмотреть файл

@ -64,6 +64,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
XPCOMUtils.defineLazyModuleGetter(this, "ScriptPreloader",
"resource://gre/modules/ScriptPreloader.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TrustedHostedAppsUtils",
"resource://gre/modules/TrustedHostedAppsUtils.jsm");
#ifdef MOZ_WIDGET_GONK
XPCOMUtils.defineLazyGetter(this, "libcutils", function() {
Cu.import("resource://gre/modules/systemlibs.js");
@ -1411,6 +1414,24 @@ this.DOMApplicationRegistry = {
return;
}
// Check if launching trusted hosted app
if (this.kTrustedHosted == app.kind) {
debug("Launching Trusted Hosted App!");
// sanity check on manifest host's CA
// (proper CA check with pinning is done by regular networking code)
if (!TrustedHostedAppsUtils.isHostPinned(aManifestURL)) {
debug("Trusted App Host certificate Not OK");
aOnFailure("TRUSTED_APPLICATION_HOST_CERTIFICATE_INVALID");
return;
}
debug("Trusted App Host pins exist");
if (!TrustedHostedAppsUtils.verifyCSPWhiteList(app.csp)) {
aOnFailure("TRUSTED_APPLICATION_WHITELIST_VALIDATION_FAILED");
return;
}
}
// We have to clone the app object as nsIDOMApplication objects are
// stringified as an empty object. (see bug 830376)
let appClone = AppsUtils.cloneAppObject(app);
@ -2295,6 +2316,23 @@ this.DOMApplicationRegistry = {
// in which case we don't need to load it.
if (app.manifest) {
if (checkManifest()) {
if (this.kTrustedHosted == this.appKind(app, app.manifest)) {
// sanity check on manifest host's CA
// (proper CA check with pinning is done by regular networking code)
if (!TrustedHostedAppsUtils.isHostPinned(app.manifestURL)) {
sendError("TRUSTED_APPLICATION_HOST_CERTIFICATE_INVALID");
return;
}
// Signature of the manifest should be verified here.
// Bug 1059216.
if (!TrustedHostedAppsUtils.verifyCSPWhiteList(app.manifest.csp)) {
sendError("TRUSTED_APPLICATION_WHITELIST_VALIDATION_FAILED");
return;
}
}
installApp();
}
return;
@ -2319,6 +2357,19 @@ this.DOMApplicationRegistry = {
app.manifest = xhr.response;
if (checkManifest()) {
app.etag = xhr.getResponseHeader("Etag");
if (this.kTrustedHosted == this.appKind(app, app.manifest)) {
// checking trusted host for pinning is not needed here, since
// network code will have already done that
// Signature of the manifest should be verified here.
// Bug 1059216.
if (!TrustedHostedAppsUtils.verifyCSPWhiteList(app.manifest.csp)) {
sendError("TRUSTED_APPLICATION_WHITELIST_VALIDATION_FAILED");
return;
}
}
installApp();
}
} else {

Просмотреть файл

@ -44,6 +44,7 @@ EXTRA_PP_JS_MODULES += [
'AppsUtils.jsm',
'OperatorApps.jsm',
'ScriptPreloader.jsm',
'TrustedHostedAppsUtils.jsm',
'Webapps.jsm',
]

Просмотреть файл

@ -7,6 +7,7 @@ support-files =
[test_apps_service.xul]
[test_bug_945152.html]
run-if = os == 'linux'
[test_tha_utils.html]
[test_manifest_helper.xul]
[test_operator_app_install.js]
[test_operator_app_install.xul]

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше